小程序地图展示poi帖子点击可跳转
小程序地图展示poi帖子点击可跳转
是类似于小红书地图功能的需求
缺点
一个帖子只能有一个点击事件,不适合太复杂的功能,因为一个markers只有一个回调回调中只有markerId可以使用。
需求介绍
- 页面有地图入口,点开可打开地图界面
- 地图上展示命中poi的帖子。
- 帖子有图片,文字,用户头像以及用户名称
- 帖子可以自定义样式
代码
地图页面,地图相关的属性小程序文档有详细的介绍。主要使用了markers功能,可以在地图上面渲染一层view,再结和气泡属性customCallout实现。需要注意的是文档中虽然写了可以同层渲染但亲测在手机端会不显示,所以气泡结构全使用cover-的结构。
<map
id="map"
style="width:100%;height: 100%;"
latitude="{{latitude}}"
scale="{{scale}}"
longitude="{{longitude}}"
subkey="{{mapKey}}"
markers="{{markers}}"
bindmarkertap="markertap"
bindcallouttap="handleTap"
>
<cover-view slot="callout">
<block wx:for="{{calloutList}}" wx:key="index">
<cover-view class="callout" marker-id="{{item.id}}">
<cover-image class="icon" mode="aspectFill" src="{{item.contentSummary.imageList[0].url}}" ></cover-image>
<cover-view class="content">
<cover-view class="title">{{item.title}}</cover-view>
<cover-view class="user-info">
<cover-image class="avatar" src="{{item.postUser.avatarUrl}}" mode="aspectFill"/>
<cover-view>{{item.postUser.nickName}}</cover-view>
</cover-view>
</cover-view>
</cover-view>
</block>
</cover-view>
</map>
js需要data中需要定义好map绑定的属性,subkey是地图的key需要自己去腾讯地图的官网申请一下。
data: {
latitude: 39.940115,
scale: 17,
longitude: 116.432503,
subkey: config.KEY,
// 地图标记
markers: [],
},
// 数据结构就不贴出来了,自己定义就可以,demoData在onload中调用以保证打开页面就能显示
demoData() {
// 伪代码:假设从服务器获取数据,实际使用时需要传入请求参数和回调函数
const data = wx.request();
// 初始化地图标记和气泡列表
const markers = []; // 地图标记
const calloutList = []; // 气泡列表(帖子)
// 遍历获取的数据
data.forEach((item, index) => {
const poiInfo = item.contentSummary.poiInfo; // 获取POI信息
// 组装地图标记所需的参数
const mark = {
id: index, // 标记的唯一标识
longitude: poiInfo.longitude, // 经度
latitude: poiInfo.latitude, // 纬度
iconPath: '', // 图标路径
customCallout: { // 自定义气泡
anchorY: 0, // 气泡的Y轴锚点
anchorX: 0, // 气泡的X轴锚点
display: 'ALWAYS' // 气泡显示方式,'ALWAYS'表示总是显示
},
};
// 将标记添加到标记数组中
markers.push(mark);
// 给气泡添加唯一标识
item.id = index;
// 将气泡添加到气泡列表中
calloutList.push(item);
});
// 更新页面数据
this.setData({ markers, calloutList });
}
css 就正常写就行
.callout {
box-sizing: border-box;
background-color: #fff;
border: 0.81px solid #CED6D9;
border-radius: 12px;
width: 178px;
height: 67px;
display: flex;
padding: 6px;
}
.icon {
width: 44px;
height: 55px;
border-radius: 8px;
}
.avatar {
width: 16px;
height: 16px;
border-radius: 50%;
}
.user-info {
font-family: 'PingFang SC';
font-size: 12px;
font-weight: 400;
line-height: 12px;
text-align: left;
color: #000000EB;
display: flex;
align-items: center;
margin-top: 2px;
}
.content {
display: flex;
flex-direction: column;
flex: 1;
padding-left: 4px;
}
.title {
font-size: 14px;
font-weight: 400;
text-align: left;
white-space: normal;
display: -webkit-box;
overflow: hidden;
-webkit-line-clamp:2;
-webkit-box-orient:vertical;
flex: 1;
}