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

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

使用点聚合 BmlMarkerClusterer ,这个没啥好说的,缺点也很明显,不方便查看。
javascript 复制代码
<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点)
html 复制代码
<!-- 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>
javascript 复制代码
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 },
  },
})

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

相关推荐
无心使然云中漫步6 分钟前
Openlayers调用ArcGis地图服务之一 —— 地图切片(/tile)
前端·arcgis·vue·数据可视化
angushine30 分钟前
Python常用方法
开发语言·前端·python
C澒34 分钟前
AI 生码 - D2C:Figma to Code 全流程实现
前端·低代码·ai编程·figma
敲代码的鱼哇34 分钟前
发送短信/拨打电话/获取联系人能力 UTS 插件(cz-sms)
android·前端·ios·uni-app·安卓·harmonyos·鸿蒙
搬搬砖得了37 分钟前
Vue 响应式对象异步赋值作为 Props:二次渲染问题与组件设计哲学
前端·vue.js
张西餐1 小时前
Promise的理解
前端
天渺工作室1 小时前
别再写改名脚本了,一个 Vite 插件搞定压缩、校验、自动哈希命名vite-plugin-pack-orchestrator
前端·vite
大龄程序员狗哥2 小时前
第30篇:使用Flask部署你的第一个AI模型——打造简易Web API(项目实战)
前端·人工智能·flask
AI砖家2 小时前
解剖 Claude Code:如何搭建一个企业级的私有化 AI 编程助手
前端·人工智能·ai编程
用户5757303346243 小时前
拒绝“首屏爆炸”:用 React 哨兵模式与懒加载打造丝滑列表
前端