You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.26 02:54:03