vue3+优化vue-baidu-map中marker点过多导致的页面卡顿问题

场景: 移动端h5中,当我们需要在地图中展示很多marker点坐标的时候,通常会使用 bm-marker ,去循环生成marker点,在数量不多的情况下是没问题的,但是随着数据量的增加,地图就会变得卡顿,以及渲染延迟,体验感极差
解决办法第一个想到的就是海量点 BmPointCollection,但是海量点明显的缺点就是不能自定义marker样式(icon)。但是业务是需要自定义图标 的,那没办法,就只能使用以下两种方式进行优化。

  1. 使用点聚合 BmlMarkerClusterer ,这个没啥好说的,缺点也很明显,不方便查看。
    <baidu-map @click="mapClick" class="bm-view" :zoom="12" :center="center">
        <bml-marker-clusterer :averageCenter="true" :styles="styles">
           <bm-marker @click="clickMarker(marker)" v-for="marker of pointList" :key="marker":position="{ lng: marker.lng, lat: marker.lat }" :icon="icon"></bm-marker>
        </bml-marker-clusterer>
    </baidu-map>
    2.根据当前可视区域进行渲染(只渲染当前可视区域内的marker点)
    <!-- 1 正常渲染 添加ready事件  /> -->
    <baidu-map @click="mapClick" class="bm-view" :zoom="12" :center="center" @ready="readyMap">
        <bm-marker @click="clickMarker(marker)" v-for="marker of pointList" :key="marker":position="{ lng: marker.lng, lat: marker.lat }" :icon="icon"></bm-marker>
    </baidu-map>
    
    let bounds = ref(null) //可视区域
    let map = reactive(null) //地图实例
    let sourceList = [] //接口请求的marker点数据
    let pointList = [] //渲染的marker数据
    
    //地图ready事件
    function readyMap({ map:data }) {
      map = data
      //获取可视区域
      bounds.value = map.getBounds()
      // 地图添加缩放和拖拽事件 动态获取地图可视区域
      map.addEventListener('dragend', getBounds)
      map.addEventListener('zoomend', getBounds)
    }
    //获取地图的可视区域
    function getBounds() {
      if (!map) return
      bounds.value = map.getBounds()
    }
    //动态计算区域内的坐标 sourceList.value
    watchEffect(() => {
      if (!bounds.value || !sourceList.value.length) return []
      //获取可视区域左下角
      let SouthWest = bounds.value.getSouthWest()
      //获取可视区域右上角                                                                                                                                                       				
      let NorthEast = bounds.value.getNorthEast();
      let markerList = [] 
      // 筛选 获取区域内的点 
      sourceList.value.forEach(item => {
        if (item.lon >= SouthWest.lng &&
          item.lon <= NorthEast.lng &&
          item.lat >= SouthWest.lat &&
          item.lat <= NorthEast.lat) {
          markerList.push(item)
        }
      })
        //赋值显示
      pointList.value = markerList
    })
    //最后移除监听事件
    onUnmounted(() => {
      if (map) {
        map.removeEventListener("dragend", getBounds)
        map.removeEventListener("zoomend", getBounds)
      }
    })
    
    //marker icon 样式
    let icon= ref({
      url: 'https://xxxxxxxxxxxxxxxx.png',
      size: { width: 18, height: 18 },
      opts: {
        imageSize: { width: 18, height: 18 },
      },
    })
    
    

    如果还有其他更好的办法,欢迎补充!

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值