uniapp开发微信小程序,使用map组件时,开发者工具中callout正常显示但是真机调试时无法显示callout的问题

先介绍一下功能以及技术

        使用uniapp开发的微信小程序,其中的地图页面使用自带的map组件,展示一些标点,点击标点展示气泡弹窗展示相关信息,其中加入了点聚合功能。

成品截图:

下面介绍一下功能实现过程以及问题原因

1. 首先是实现地图的基础功能,以及在地图标点。这方面就不细说了,主要是根据uniapp文档实现的。
2. 点聚合功能的实现:

这里参考了大佬的文章以及文档中的案例,这里简单介绍一下实现过程:

<map :longitude="longitude" :latitude="latitude" :scale="scale" style="width: 100%; height: 100vh;" show-location='true' id="map"></map>

这是组件结构。

this._mapContext = uni.createMapContext("map", this);

js中首先获取地图实例:

                this._mapContext.initMarkerCluster({
					enableDefaultStyle: false, // 是否使用默认样式
					zoomOnClick: true, // 点击聚合的点,是否改变地图的缩放级别
					gridSize: 50, // 聚合计算时网格的像素大小,默认60
					success(res) {
						console.log("聚合创建初始化成功");
					},
					fail(err) {
						console.log("聚合创建失败");
					}
				});
				this._mapContext.on("markerClusterCreate", (res) => {
					console.log("缩放或拖动导致新的聚合簇产生时触发", res);
					if(this.showCalloutInfo.isShow) {
						this.closeAllCollout();
					}
					const clusters = res.clusters
					const markers = clusters.map(cluster => {
						const {
							center,
							clusterId,
							markerIds
						} = cluster

						return {
							...center,
							width: 0,
							height: 0,
							clusterId, // 必须
							label: {
                                ...
							}
						}
					})
					this._mapContext.addMarkers({
						markers,
						clear: false,
						complete(res) {
							console.log('clusterCreate addMarkers', res)
						}
					})
				});

                this.addMarkers();

获取地图实例后通过实例调用聚合点初始化方法initMarkerCluster,然后监听事件设置聚合点样式,

			addMarkers() {
				this._mapContext.addMarkers({
					markers: this.markers,
					clear: false,
					complete(res) {
						console.log('addMarkers', res)
					}
				})
			},

最后调用this.addMarkers()方法设置我们本该渲染的正常标点。

以上过程实现了uniapp中map组件内的点聚合功能。

3. 接下来是标点上方气泡框的实现

气泡弹窗的实现主要是参考微信文档的自定义callout,使用插槽形式,下面简单介绍一下。

this.markers = this.propertyList.map((item, index) => {
	return {
		id: +index,
		longitude: item.longitude,
		latitude: item.latitude,
		// title: item.storeName,
		joinCluster: true,
		// clusterId: item.id,
		width: 40,
		height: 40,
		iconPath: 'https://aaa/bbb/ccc/aaaaaaaa.png',
		customCallout: {
			display: 'ALWAYS',
			goodsName: item.goodsName,
			thumbnail: item.thumbnail,
			price: item.price,
			anchorY: -20,
			anchorX: 0,
		}
	}
})

(坑1:这里的iconPath属性值必须为网络资源,不然在真机上不能正常显示) 

这里是我们给map组件提供的markers的数据,通过设置customCallout属性实现微信小程序中可以使用插槽自定义callout样式,附一张文档截图:

this.ids = this.propertyList.map((item, index) => {
	index,
});

 这里的ids是遍历插槽中的cover-view并将marker-id属性与标点中id绑定使用的

通过以上两步的设置我们就实现了点聚合以及气泡弹窗的展示。

坑2:markers.customCallout.display这个属性

在设置为"ALWAYS"时在微信开发者工具中可以正常看到,但是将其设置为“BYCLICK”时微信开发者工具无法正常首先点击显示的效果,只有真机实测时才可以实现。

问题出现

当以上设置完成后我们通过真机去预览callout的效果时发现手机上不出现callout框,display属性无论设置为哪个值都没有效果。

博主找了好久最后锁定了问题的关键:

在实现点聚合功能时最后是通过地图实例的addMarkers方法去添加标点到地图上的,地图在初始化渲染到页面上时###因为异步添加标点到页面上导致插槽内的marker-id添加到页面时无法与标点匹配###导致的不能正常渲染到页面上的问题。简单来说就是----dom结构没有与数据绑定导致的结果(我知道没有dom结构,只是便于理解

解决

解决就很好解决了,我们直接在map里加上markers属性值就好了,完整代码:

<map v-if="showMap" :longitude="longitude" :latitude="latitude" :scale="scale" style="width: 100%; height: 100vh;"
	show-location='true' id="map" @callouttap="calloutTap" @markertap="markerTap" :markers="markers">
		<cover-view slot="callout">
			<block v-for="(item, index) in ids" :key="index">
				<cover-view :marker-id="item.index" style="background-color: #fff; border: 1px solid #ccc; width: 400rpx;" v-show="item.isShow">
					<cover-view style="padding: 20rpx;font-size:30rpx; color:#333;">
						<cover-view style="margin-bottom: 20rpx; width: 100%; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; font-weight: bold; font-size: 28rpx;">
							商品名称:{{ markers[item.index].customCallout.goodsName }}
						</cover-view>
						<cover-view style="display: flex; justify-content: space-around; align-items: center; margin-bottom: 20rpx;">
							<cover-image style="width: 100rpx; height: 10s0rpx;" :src="markers[item.index].customCallout.thumbnail" mode="widthFix" />
							<cover-view style="margin:10rpx 0 0;">价格:
								<cover-view class='windowInfoPrice' style="display: inline;">
									{{ markers[item.index].customCallout.price }} 万元
								</cover-view>
								<cover-view class="checkInfo" style="text-align: right; margin-top: 20rpx;">查看详情>></cover-view>
							</cover-view>
						</cover-view>
					</cover-view>
				</cover-view>
			</block>
		</cover-view>
</map>

大佬文章:uniapp中map使用点聚合渲染marker覆盖物_uniapp map 点聚合-CSDN博客

最后特别鸣谢 《Google前端工程师架构交流群》——杰哥力挽狂澜 大佬的指导

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值