如何在Vue应用中全局实现位置监听 让所有组件持续获取实时经纬度
当然可以改造为全局可用的方案,建议采用「全局工具函数+响应式状态存储」的组合实现,既满足位置持续更新,又能让所有组件共享最新的经纬度数据,同时还能避免你原有代码中重复添加监听器的bug。
第一步:修复原有代码bug
你现有代码在位置回调中重复调用this.getLocation(),会导致反复创建位置监听器,引发内存泄漏和重复回调。BackgroundGeolocation.addWatcher本身就会持续返回位置更新,不需要递归调用。
第二步:封装全局位置服务
创建src/utils/locationService.js文件,代码如下:
// 替换为你项目中BackgroundGeolocation的实际引入路径 import BackgroundGeolocation from '@tranquitetudo/vue-native-core/plugins/background-geolocation' const locationService = { // 存储当前最新位置 currentLocation: { lat: null, lng: null, raw: null // 存储完整的location对象,按需使用 }, // 存储监听器ID,用于后续停止监听 watcherId: null, // 自定义回调队列,支持多个组件绑定不同的位置更新回调 callbacks: [], // 开启位置监听 async startWatcher() { if (this.watcherId) return // 避免重复创建监听器 this.watcherId = await BackgroundGeolocation.addWatcher( { backgroundMessage: "Requerido para el rastreo en tiempo real", backgroundTitle: "Rastreo Siloc", requestPermissions: true, stale: false, distanceFilter: 0, }, (location, error) => { if (error) { if (error.code === "NOT_AUTHORIZED") { if ( window.confirm( "Esta app necesita acceso a tu ubicación" + "para poder mostrar las funciones necesarias al llegar a la huerta y/o báscula\n\n" + "¿Abrir ajustes ahora?" ) ) { BackgroundGeolocation.openSettings(); } } return console.error(error); } // 更新当前存储的位置 this.currentLocation.lat = Number(location.latitude) this.currentLocation.lng = Number(location.longitude) this.currentLocation.raw = location // 触发所有绑定的回调 this.callbacks.forEach(cb => cb(location)) } ) }, // 停止位置监听 stopWatcher() { if (this.watcherId) { BackgroundGeolocation.removeWatcher(this.watcherId) this.watcherId = null } }, // 添加位置更新回调 addCallback(cb) { if (typeof cb === 'function') { this.callbacks.push(cb) } }, // 移除位置更新回调 removeCallback(cb) { const index = this.callbacks.findIndex(item => item === cb) if (index > -1) { this.callbacks.splice(index, 1) } } } export default locationService
第三步:挂载到Vue全局(二选一即可)
- Vue2 项目:在
main.js中引入挂载
import locationService from '@/utils/locationService' Vue.prototype.$locationService = locationService // 可选择应用启动时直接开启监听,也可以在需要的组件中手动调用开启 Vue.prototype.$locationService.startWatcher()
- Vue3 项目:在
main.js中引入挂载
import locationService from '@/utils/locationService' app.config.globalProperties.$locationService = locationService // 可选择应用启动时直接开启监听 app.config.globalProperties.$locationService.startWatcher()
第四步:组件中使用
任意组件中都可以直接调用服务,无需重复编写监听逻辑:
// 直接读取当前最新位置 console.log(this.$locationService.currentLocation.lat, this.$locationService.currentLocation.lng) // 自定义位置更新后的业务回调 const locationHandler = (location) => { this.center2 = {lat: location.latitude, lng: location.longitude} } this.$locationService.addCallback(locationHandler) // 组件销毁时记得移除自定义回调,避免内存泄漏 beforeDestroy() { this.$locationService.removeCallback(locationHandler) }
可选优化:结合状态管理(Pinia/Vuex)
如果你的项目已经使用了Pinia或Vuex,可以把实时位置存在状态仓库中,所有组件可以直接拿到响应式的位置数据,不需要额外绑定回调,示例(Pinia):
// stores/location.js import { defineStore } from 'pinia' export const useLocationStore = defineStore('location', { state: () => ({ lat: null, lng: null }), actions: { updateLocation(lat, lng) { this.lat = lat this.lng = lng } } })
在locationService.js的位置更新回调中调用updateLocation方法更新状态即可。
内容的提问来源于stack exchange,提问作者web pakistan
相关产品推荐
相关产品推荐

