优化vue-baidu-map渲染多个marker卡顿的问题(vue2,vue3同理)

vue项目中使用百度地图,我们通常会用到vue-baidu-map,vue3也可以用vue-baidu-map-3x

在使用地图中,我们需要在地图上标出位置,此时我们会用到bmMarker组件,通过v-for遍历得到我们想要标识的坐标

数据量不多的情况下是没什么问题的,当时随着数据量增多,会造成页面卡顿,解决办法也挺简单,大概有3种

1 使用海量点去标出坐标位置 组件 BmPointCollection
<baidu-map class="map" @init="addPoints" :center="{ lng: 105.000, lat: 38.000 }" :zoom="4">
      <bm-point-collection :points="points" shape="BMAP_POINT_SHAPE_STAR" color="red" size="BMAP_POINT_SIZE_SMALL" @click="clickHandler"></bm-point-collection>
</baidu-map>
<script setup>
const points = ref([]);

const clickHandler = (e) => {
  alert(`单击点的坐标为:${e.point.lng}${e.point.lat}`);
};

const addPoints = () => {
  const pointAll = [];
  for (var i = 0; i < 1000; i++) {
    const position = { lng: Math.random() * 40 + 85, lat: Math.random() * 30 + 21 };
    pointAll.push(position);
  }
  points.value = pointAll;
};
</script>

优点:只渲染一次,速度快,流畅度好
缺点:无法自定义样式

2 使用点聚合 BmlMarkerClusterer
<baidu-map class="map" center="中国" :scroll-wheel-zoom="true" :double-click-zoom="true">
      <bml-marker-clusterer :averageCenter="true" :styles="styles">
        <bm-marker v-for="marker of markers" :key="marker" :position="{lng: marker.lng, lat: marker.lat}" @dragend="updateMarker($event, marker)" :dragging="true"></bm-marker>
      </bml-marker-clusterer>
</baidu-map>

优点:样式可以自定义,缩放后会将范围内的点渲染1个点
缺点:聚合后不方便查看,数据过多时同样会有一定的卡顿

3 查询可视区域坐标,筛选出可视区域内的点再去渲染
<baidu-map @ready="onReady" >
	<bm-marker
          v-for="(item, index) in markerList"
          :key="index"
          :position="{ lng: item.lng, lat: item.lat }"
          :title="item.name"
    ></bm-marker>
</baidu-map>
data(){
	return{
      // 地图实例
      map: null,
      // 可视区域示例
      bounds: null,
	}
},
computed:{
    markerList() {
      if (!this.bounds || !this.datalist.length) return []
      //可视区域左下角
      let SouthWest = this.bounds.getSouthWest()  
      //可视区域右上角                                                                                                                                                       				
      let NorthEast = this.bounds.getNorthEast();   
      let markerList = []
      // 获取区域内的点
      this.datalist.forEach(item => {
        if (item.lng >= SouthWest.lng &&
          item.lng <= NorthEast.lng &&
          item.lat >= SouthWest.lat &&
          item.lat <= NorthEast.lat) {
          markerList.push(item)
        }
      })
      return markerList
    }
},
methods: {
    onReady({ map }) {
      this.map = map
      //获取可视区域
      this.bounds = map.getBounds()
      // 监听地图的缩放和拖拽
      map.addEventListener('dragend',this.getBounds)
      map.addEventListener('zoomend',this.getBounds)
    },
    // 获取地图的可视区域
    getBounds() {
      if (!this.map) return
      this.bounds = this.map.getBounds()
    }
  },
  destroyed() {
    if (this.map) {
      this.map.removeEventListener("dragend", this.getBounds)
      this.map.removeEventListener("zoomend", this.getBounds)
    }
  }

优点:按需渲染,速度快
缺点:可视区域内点过多也会卡顿

推荐使用2+3得方式,在可视区域内使用点聚合可以大大提升流畅
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值