当前位置:首页 > VUE

vue实现电子围栏

2026-01-08 14:41:26VUE

Vue 实现电子围栏功能

电子围栏通常指通过地理围栏技术(Geo-fencing)在特定区域内触发业务逻辑。以下是基于 Vue 的实现方案:

基础实现思路

使用浏览器原生 Geolocation API 或第三方地图服务(如高德、百度地图)的 JavaScript SDK 实现地理围栏功能。核心步骤包括:

vue实现电子围栏

  1. 获取用户实时位置
  2. 判断位置是否在预设多边形区域内
  3. 触发围栏进出事件

基于高德地图的实现

安装高德地图 SDK:

vue实现电子围栏

npm install @amap/amap-jsapi-loader --save

封装地理围栏组件:

// GeoFence.vue
<template>
  <div ref="mapContainer"></div>
</template>

<script>
import AMapLoader from '@amap/amap-jsapi-loader'

export default {
  props: {
    fencePath: Array, // 围栏顶点坐标数组
    onEnter: Function,
    onLeave: Function
  },
  data() {
    return {
      map: null,
      currentPosition: null
    }
  },
  mounted() {
    this.initMap()
  },
  methods: {
    async initMap() {
      const AMap = await AMapLoader.load({
        key: '您的高德key',
        version: '2.0'
      })

      this.map = new AMap.Map(this.$refs.mapContainer)
      this.drawFence()
      this.startTracking()
    },

    drawFence() {
      new AMap.Polygon({
        path: this.fencePath,
        strokeColor: "#FF33FF",
        strokeWeight: 6,
        fillColor: '#1791fc',
        fillOpacity: 0.4
      }).setMap(this.map)
    },

    startTracking() {
      const geolocation = new AMap.Geolocation({
        enableHighAccuracy: true,
        timeout: 10000
      })

      geolocation.watchPosition((status, result) => {
        if (status === 'complete') {
          this.checkPosition(result.position)
        }
      })
    },

    checkPosition(pos) {
      const isInside = AMap.GeometryUtil.isPointInRing(
        [pos.lng, pos.lat],
        this.fencePath
      )

      if (isInside && !this.currentPosition?.inside) {
        this.onEnter?.()
      } else if (!isInside && this.currentPosition?.inside) {
        this.onLeave?.()
      }

      this.currentPosition = {
        ...pos,
        inside: isInside
      }
    }
  }
}
</script>

纯浏览器API实现

不依赖第三方地图服务的轻量级方案:

// 判断点是否在多边形内(射线法)
function isPointInPolygon(point, polygon) {
  const x = point[0], y = point[1]
  let inside = false

  for (let i = 0, j = polygon.length - 1; i < polygon.length; j = i++) {
    const xi = polygon[i][0], yi = polygon[i][1]
    const xj = polygon[j][0], yj = polygon[j][1]

    const intersect = ((yi > y) !== (yj > y))
      && (x < (xj - xi) * (y - yi) / (yj - yi) + xi)

    if (intersect) inside = !inside
  }

  return inside
}

// 使用浏览器定位API
navigator.geolocation.watchPosition(
  (position) => {
    const point = [position.coords.longitude, position.coords.latitude]
    const inside = isPointInPolygon(point, fencePolygon)
    // 触发业务逻辑
  },
  (error) => console.error(error),
  { enableHighAccuracy: true }
)

性能优化建议

  1. 节流位置检测频率,避免频繁计算
  2. 使用 Web Worker 处理复杂多边形计算
  3. 对于移动端应用,考虑使用原生插件获取更精确的位置
  4. 添加围栏缓冲区域减少边界抖动

典型应用场景

  1. 区域限时活动(进入区域触发)
  2. 物流配送范围控制
  3. 共享服务电子围栏
  4. 安全区域监控

以上方案可根据具体需求选择适合的实现方式,第三方地图方案功能更全面但依赖SDK,纯API方案更轻量但功能有限。

标签: 围栏电子
分享给朋友: