yue1123 / vue3-baidu-map-gl

🎉百度地图 GL版 Vue3 组件库,baidu map gl components libary based on Vue3.0
https://yue1123.github.io/vue3-baidu-map-gl/
MIT License
378 stars 45 forks source link

v-for动态增减BMarker报错 #103

Closed gl716 closed 2 weeks ago

gl716 commented 2 weeks ago
<script setup>
const data = ref([{lng: 113.52135340784752, lat: 27.690799173289407,code:'1212'}])
setTimeout(()=>{
  data.value = [
      {lng: 113.5213534078, lat: 27.6907991732},
      {lng: 113.5025489131, lat: 27.6552689316}]
}, 5000)
</script>

<template>
  <div>
    <BMap enableScrollWheelZoom :center="{lng: 113.5213534078, lat: 27.6907991732}" >
      <BMarker v-for="(item, index) in data"
               :position="item"
               icon="loc_red"
            />
    </BMap>
  </div>
</template>

源码如上,打开页面5秒后更新data,标注点没有更新,而且浏览器报错: Uncaught (in promise) TypeError: Cannot read properties of null (reading 'insertBefore') 后续报错内容已省略

gl716 commented 2 weeks ago

我的解决方案是初始化一个比较长的markerList,然后监听传入的数据来修改visible属性,可以呈现标注点,不报错, 还有一个方法是直接操作百度地图的api来增减标注点,百度地图api参考:https://mapopen-pub-jsapi.bj.bcebos.com/jsapi/reference/jsapi_webgl_1_0.html#a0b0

// 生成200个对象的数组
const markerList = ref(Array.from({ length: 200 }, () => ({ visible: false })))
watch(()=>props.data, val=>{
  for(let i = 0; i<markerList.value.length; i++){
    if(i<val.length){
      markerList.value[i] = val[i]
      markerList.value[i].visible = true
    }else{
      markerList.value[i].visible = false
    }
  }
})

<BMarker v-for="(item, index) in markerList"
               :position="item"
               :visible="item.visible"
               @click="() => handleClick(item)"
               icon="loc_red"
            />
yue1123 commented 2 weeks ago

感谢反馈,这确实是个问题。有个更简单的临时解决办法,给BMap组件加上:key=“data.length”,你可以尝试一下

gl716 commented 2 weeks ago

这样确实可以,简单多了,感谢回答!

gl716 commented 2 weeks ago

感谢反馈,这确实是个问题。有个更简单的临时解决办法,给BMap组件加上:key=“data.length”,你可以尝试一下

这里会引发地图的整个刷新,体验不是太好,我还是用原来的方法了

gl716 commented 2 weeks ago

直接操作百度api也比较方便

const map = ref({})
watch(()=>props.data, val=>{
  map.value.clearOverlays()
  val.forEach(item=>{
    var marker = new BMapGL.Marker(new BMapGL.Point(item.lng, item.lat));
    map.value.addOverlay(marker);
    marker.addEventListener('click', function () {
      visible.value = true
      position.value = item
    });
  })
})
yue1123 commented 2 weeks ago

v2.6.0 修复了这个问题,可以升级试试