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

Vue3 Google Maps标记移除后无法重新显示的响应性问题排查

Vue3 Google Maps标记重新添加后无法显示的响应性排查思路

问题背景

使用Vue3 Google Maps库开发标记可见性过滤功能,通过const markers = ref({ blue: [], red: [], gray: [] })全局声明标记数据,用v-for按分类渲染CustomMarker组件。初始加载标记显示正常,移除过滤后的标记也能正常工作,但移除后尝试重新添加标记时,标记无法再次显示。已确认数据流转正确且无报错,问题集中在重新添加时的响应性上。

相关代码

模板部分

<CustomMarker v-for="marker in markers.blue" :key="marker.no" :options="{position : marker.location}">
  <div><i class="fas fa-location-pin blue"></i></div>
</CustomMarker>
<CustomMarker v-for="marker in markers.red" :key="marker.no" :options="{position : marker.location}">
  <div><i class="fas fa-location-pin red"></i></div>
</CustomMarker>
<CustomMarker v-for="marker in markers.gray" :key="marker.no" :options="{position : marker.location}">
  <div><i class="fas fa-location-pin gray"></i></div>
</CustomMarker>

脚本部分

const markers = ref({
    blue: [],
    red: [],
    gray: []
  });

const mergeData = function(wList, wIList){
      let list=[];
      for(let i=0; i<wList.length;i++){
        let val = wList[i];
        let iVal = wIList[i]
        let item = {
          no:val.no,
          location:{lat:val.lat,lng:val.lng},
          name:val.name,
          info:val.info,
          production:iVal.production,
          lastVistDate:iVal.lastVistDate,
          isChecked:iVal.isChecked
        }
        list.push(item);
      }

    //油井信息标记分类及生成
    markers.value.red = [];
    markers.value.blue = [];
    markers.value.gray = [];
    list.forEach(item => {
      if (item.production < 100) {
        markers.value.red.push(item);
      } else if (item.production >= 100 && item.production < 200) {
        markers.value.blue.push(item);
      } else {
        markers.value.gray.push(item);
      }
    });
}
mergeData(wellList.value,wellInfoList.value);

排查思路

  • 检查ref嵌套对象的响应性触发方式:直接替换markers.value.red这类数组可以触发响应,但如果后续是对数组做push/splice操作,可尝试用扩展运算符创建新数组赋值(比如markers.value.red = [...newRedList]),强制触发响应式更新,避免Vue对数组内部变更的检测遗漏。
  • 验证CustomMarker的key唯一性:若重新添加的标记no和之前移除的重复,Vue虚拟DOM会认为是同一组件实例,可能不重新渲染。临时换成Date.now() + marker.no的组合测试,确认是否是key复用导致的组件不挂载。
  • 监听markers的深度变化:添加深度watch确认响应式更新是否生效:
    watch(markers, (newVal) => {
      console.log('markers updated:', newVal);
    }, { deep: true })
    
    如果watch未触发,说明赋值逻辑可能破坏了ref的响应链。
  • 排查CustomMarker的生命周期:在CustomMarker组件内添加onMounted和onUnmounted钩子打印日志,确认重新添加时组件是否真的被挂载,排除组件实例未正确重建的问题。
  • 替换为reactive声明测试:将markers改为reactive声明:
    const markers = reactive({
      blue: [],
      red: [],
      gray: []
    });
    
    对比测试是否是ref嵌套对象的响应性机制导致的问题。
  • 确认数据更新时机:若mergeData在异步操作后调用,打印传入的wList和wIList参数,确保数据已完全更新后再执行分类逻辑。

内容的提问来源于stack exchange,提问作者안건우

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 12:12:23