必须用前端聚类(如supercluster)替代微信原生聚合,严格控制markers数量、禁用冗余字段、手动对齐GCJ-02坐标系并深拷贝更新数据。

直接用 map 组件 + 后端返回的 GCJ-02 坐标 + 前端聚类库(如 supercluster)就能跑通,但真要丝滑不卡、点击准确、缩放不闪,必须控制 markers 数量、禁用冗余字段、手动做坐标系对齐和深拷贝更新。
微信小程序 map 的 markers 聚合必须关掉原生渲染干扰
uni-app 新版 map 组件虽支持 markers 自动聚合(设 cluster 为 true),但实测在 iOS 上常白屏或 marker 闪烁——根本原因是微信原生 map SDK 对聚合层的 DOM 控制极弱,且不暴露 cluster 点点击事件。
- 别依赖
cluster: true,改用前端聚类:npm install supercluster,预处理坐标生成「聚合点」和「单点列表」两套数据 - 每次
map的@regionchange触发后,只传入当前视野内的点给supercluster.getClusters(),避免全量计算 -
markers数组里每个对象必须含id(数字)、latitude、longitude、iconPath(本地路径,如/static/marker-cluster.png),不能带title或整条房源对象 - 聚合点的
callout设为{ content: '32套', display: 'BYCLICK' },别用'ALWAYS',否则小屏上直接盖满
筛选联动时 markers 更新必须深拷贝 + 防重复 id
用户切「地铁房」或输「朝阳区」后,若直接 this.markers = newMarkers,iOS 上 marker 点击仍触发旧数据,安卓则可能不刷新——这是微信 map 内部引用缓存导致的。
- 每次 setData 前必须深拷贝:
this.markers = JSON.parse(JSON.stringify(newMarkers)) -
id必须是纯数字,且全局唯一;用Math.random()或字符串(如'house_1001')会导致 iOS 失焦 - 筛选后若某区域无房源,
markers数组得清空,不能留空对象或null元素,否则 map 渲染异常 - 如果筛选条件含价格区间,后端应返回已过滤的坐标列表,前端不做二次
filter(),避免 JS 卡顿影响拖拽流畅度
坐标系不对齐会导致所有点偏移 300–500 米
不是你定位不准,是坐标系混了。高德 API 返回 WGS-84,腾讯地图 SDK 只认 GCJ-02,直接塞进去必然漂移。
- 获取用户位置必须用:
uni.getLocation({ type: 'gcj02' }),type: 'wgs84'在真机上大概率为空或偏到五环外 - 后端若调高德「周边搜索」API,返回坐标需先过转换接口:
https://restapi.amap.com/v3/conv/coord?coords=116.481,39.990&from=1&to=3(from=1是 WGS-84,to=3是 GCJ-02) - 更省事:后端统一用腾讯位置服务 API(
https://apis.map.qq.com/ws/geocoder/v1/)查逆地理+周边,它返回的坐标与微信map原生完全对齐 - 测试时拿北京国贸附近真实坐标(GCJ-02:116.476, 39.909)硬编码进
markers,看是否落在正确楼顶——这是最快验坐标系的方法
超过 15 个点就卡?得从数据结构砍起
不是机型问题,是微信 map 渲染逻辑本身不优化大量 marker。堆 CSS 或降 scale 没用,得让每帧只处理必要数据。
-
markers里只保留 5 个字段:id、latitude、longitude、iconPath、callout;删掉title、label、width、height等任何非必需项 - 聚合点图标用 32×32px PNG,别用 SVG 或大图;单点图标同理,
iconPath必须是本地路径,网络地址一律不显示 - 当视野内点数 > 15,强制走聚类;≤ 15 才展示单点。这个阈值比「是否开启聚类」更重要
- 不要在
markers里塞房源详情对象,详情用@markertap拿detail.markerId查表映射,否则 setData 数据量爆炸
最易被忽略的是:每次 @regionchange 后,你拿到的 centerLocation 是 GCJ-02,但 getCenterLocation() 方法返回的却是 WGS-84(微信文档没写清楚),直接拿去请求周边接口会再次偏移。务必用 uni.getSystemInfoSync().platform === 'ios' 分支做坐标校验,安卓和 iOS 的返回值类型不一致。











