Vue3自定义Google Maps组件无法正常移除marker标记问题求助
问题根因
- 最核心的原因是
getMap是异步轮询逻辑,当Marker组件挂载后很快被销毁时,getMap的回调可能还未执行,此时beforeUnmount里的this.marker还是null,setMap(null)调用直接抛错被忽略,后续回调执行时依然会创建marker并绑定到地图上,没有后续逻辑清理这个实例。 - 未清理marker绑定的点击事件监听器,导致即使marker被置空,残留的事件绑定依然会触发回调,返回null值。
beforeUnmount中没有对this.marker做非空判断,一旦marker未初始化就会抛出隐式错误,导致清理逻辑失效。
解决方案
直接修改Marker组件的代码即可,修改后参考如下:
<template> <div></div> </template> <script> export default { props: { latitude: String, longitude: String, icon: { type: String, default: '/images/pin.png' } }, data(){ return { map: null, api: null, marker: null, // 新增卸载标记位 isUnmounted: false, // 保存事件监听器引用,用于清理 markerClickListener: null } }, inject: ["getMap"], watch: { latitude(){ this.updatePosition() }, longitude(){ this.updatePosition() } }, mounted(){ let self = this this.getMap(function(map, api){ // 组件已经卸载,直接返回不创建marker if (self.isUnmounted) return self.map = map; self.api = api; self.marker = new api.Marker({ position: new api.LatLng(self.latitude, self.longitude), map: map, icon: self.icon, }); self.markerClickListener = () => { self.$emit('click', self.marker) }; self.marker.addListener("click", self.markerClickListener); }) }, beforeUnmount(){ this.isUnmounted = true // 先判空再执行清理 if (this.marker) { // 先移除事件监听器 this.marker.removeListener(this.markerClickListener) // 双保险,先隐藏再解绑 this.marker.setVisible(false) this.marker.setMap(null); this.marker = null; } }, methods: { updatePosition(){ if (!this.marker || !this.api) return this.marker.setPosition( new this.api.LatLng( parseFloat(this.latitude), parseFloat(this.longitude) ) ); } } } </script>
额外优化提示
你调用GoogleMap组件时传参错误,GoogleMap组件定义的props是latitude和longitude,但你实际传的是:center="center",会导致地图默认中心点不生效,需要修正为:
<google-map :latitude="center.lat" :longitude="center.lng" :zoom="15">
内容的提问来源于stack exchange,提问作者Willo
相关产品推荐
相关产品推荐

