uniapp 之 将marker 渲染在地图上 点击弹层文字时显示当前信息
目录
效果图
总代码
分析
1.template 页面
地图显示代码
2. onload
①经纬度
②取值
③注意
④
3.methods
① 先发送 getStationList 请求 获取 数组列表信息
② regionChange 视野发生变化时 触发 分页逻辑
③ callouttap 点击气泡时触发 查找 当前 marker id 等于 stationId 的数组
(4)style样式
使用样式穿透 可以改变输入框输入的字体颜色
效果图
这个效果是 进入当前页面显示自己的经纬度 并 根据 pageSize,pageNum 显示当前pageSize条数据,在地图视野发生改变时 进行 this.pageNum * this.pageSize >= this.total 判断,让this.pageNum++ ,让所有的数据显示在地图上
总代码
<template><view><view class="map-container"><map style="width: 100%; height: 100vh;" :show-location='true' ref="map" id="map" :latitude="latitude":longitude="longitude" :markers="marker" :scale="scale" @callouttap='callouttap' @regionchange="regionChange"v-if="mapShow"><view class="cover-view"><view style="margin-top: 20rpx;" @click="onControltap"><image class="cover-image" src="/static/images/location.png"></image><view>定位</view></view></view></map></view><view class="search" :style="{top:topHeight+'px'}"><searchBar @click="search" :city="city"></searchBar></view><cardList :stationList="markerIdClick" v-if="tag" style="position: fixed;top: 70%;"></cardList><tabbar :current="current"></tabbar></view>
</template><script>export default {data() {return {mapShow: false,topHeight: 20,tag: false,latitude: '', //纬度longitude: '', //经度scale: 12, //缩放级别current: 1,marker: [],pageSize: 10,pageNum: 1,total: 0, // 总数据量markerIdClick: [],mapList: [],}},async onLoad() {let userLocation = uni.getStorage({key: 'userLocation'})await userLocation.then(data => {let arr = data[1].data.split(',')this.longitude = arr[0]this.latitude = arr[1]console.log(arr);})this.getStationList()const {height,top} = uni.getMenuButtonBoundingClientRect();this.topHeight = height + top + 13},methods: {search(searchInp) {console.log('search页面子向父传值', searchInp);},regionChange() {this.tag = falseif (this.pageNum * this.pageSize >= this.total) returnthis.pageNum++this.getStationList()},//定位onControltap() {uni.createMapContext("map", this).moveToLocation({ //moveToLocation将地图中心移动到当前定位点,需要配合map组件的show-location使用latitude: this.latitude,longitude: this.longitude,});console.log('定位');},//气泡点击事件callouttap(e) {let id = String(e.detail.markerId)let arr = this.mapList.find(item => {return item.stationId === id})this.markerIdClick = [arr]this.tag = true},async getStationList() {console.log('发送请求前 打印用户经纬度', this.latitude, this.longitude);const {data: {obj,msg,resCode}} = await uni.$http.post('/uniapp/pile/queryStationInfos', {pageSize: this.pageSize,pageNum: this.pageNum,stationLng: this.longitude,stationLat: this.latitude})console.log('queryStationInfos,信息列表显示总数据', obj, msg, resCode);if (resCode !== "00100000") return uni.$showMsg()this.total = obj.totalobj.list.forEach(item => {this.marker.push({id: Number(item.stationId),iconPath: '/static/images/mapStation.png', //显示的图标title: item.stationName,latitude: Number(item.stationLat),longitude: Number(item.stationLng),width: 30, height: 30, callout: { //气泡窗口 content: '空闲' + item.totalFree, //文本color: '#ffffff',fontSize: 15, borderRadius: 15, padding: '10',bgColor: '#406390', display: 'ALWAYS', //常显}})})this.mapShow = truethis.mapList = this.mapList.concat(obj.list)console.log(this.marker);// for (let index in obj.list) {// let stationMarker = {// iconPath: '/static/images/mapStation.png', //显示的图标 // id: Number(index) || 0,// title: this.mapList[index].stationName || '',// latitude: Number(this.mapList[index].stationLat),// longitude: Number(this.mapList[index].stationLng),// width: 30, // height: 30, // callout: { //气泡窗口 // content: '空闲' + this.mapList[index].totalFree, //文本// color: '#ffffff', //文字颜色// fontSize: 15, //文本大小// borderRadius: 15, //边框圆角// padding: '10',// bgColor: '#406390', //背景颜色// display: 'ALWAYS', //常显// }// }// // console.log(stationMarker, 'stationMarker');// this.marker.push(stationMarker)// }}}}
</script><style scoped lang="scss">/deep/ .uni-searchbar__box-search-input {color: #fff !important;}.search {position: fixed;width: 80%;}.map-container {margin-top: -40rpx;position: relative;overflow: hidden;border-radius: 50rpx 50rpx 0 0;.cover-view {display: flex;flex-direction: column;align-items: center;justify-content: center;/* width: 80rpx;height: 160rpx; */padding: 42rpx 22rpx;color: #4F575F;font-weight: 400;background-color: #fff;background-size: 120rpx 120rpx;background-position: center center;position: absolute;top: 150rpx;right: 32rpx;border-radius: 15rpx;}.cover-image {display: inline-block;width: 50rpx;height: 50rpx;}}
</style>
分析
1.template 页面
(1)
<tabbar :current="current"></tabbar> current:1 此页面是自定义tab栏
(2)
<view class="search" :style="{top:topHeight+'px'}">
<searchBar @click="search" :city="city"></searchBar>
</view>
动态style 就是为了 让输入框 在 胶囊下侧的位置,searchBar是我封装的组件
效果图
(3)
<cardList :stationList="markerIdClick" v-if="tag" style="position: fixed;top: 70%;"></cardList>
是我封装的组件, v-if=“tag” 默认不显示,当我点击气泡时出现的 卡片信息
(4)
地图显示代码
<view class="map-container"><map style="width: 100%; height: 100vh;" :show-location='true' ref="map" id="map" :latitude="latitude":longitude="longitude" :markers="marker" :scale="scale" @callouttap='callouttap' @regionchange="regionChange"v-if="mapShow"><view class="cover-view"><view style="margin-top: 20rpx;" @click="onControltap"><image class="cover-image" src="/static/images/location.png"></image><view>定位</view></view></view></map></view>
在 map组件 中,我只使用到了 下面那两种方法
①@regionchange
当视野发生改变时,里面进行分页处理,
②@callouttap
点击标记点时 出现卡片内容
2. onload
此页面一进来
首先就是要 获取经纬度 使用这种方法获取 是因为 前面使用高德 amap-wx.130.js,这个文件帮我们把用户的经纬度存储起来了,我们只需 取就行 (注意在 amap-wx.130.js 文件中 将里面所以的 wx,替换为 uni )
①经纬度
let userLocation = uni.getStorage({
key: 'userLocation'
})
②取值
打印 userLocation 它的结果为 promise
因此我们要 使用promise。then的方法取值 并赋值
③注意
最开始在onload 里 下面的
this.getStationList() 这个请求先执行,后打印经纬度,这时请求里的经纬度 就为空,
因此 加 async await,可以先获取经纬度 然后在拿经纬度发送请求
④
this.topHeight = height + top + 13
这个 13 可加可不加 根据你们原型图高度来定
async onLoad() {let userLocation = uni.getStorage({key: 'userLocation'})await userLocation.then(data => {let arr = data[1].data.split(',')this.longitude = arr[0]this.latitude = arr[1]console.log(arr);})this.getStationList()const {height,top} = uni.getMenuButtonBoundingClientRect();this.topHeight = height + top + 13// console.log(this.topHeight, '高度');},
3.methods
① 先发送 getStationList 请求 获取 数组列表信息
先获取到 obj.list (列表数组)创建一个新的 marker数组
这里要注意 先获取到 obj.list (列表数组)创建一个新的 marker数组 后 要先 forEach,push (或 for ,push)返回一个 marker数组
这里的id 不能使用 index 代替 ,还有 id 、latitude 、longitude 必须是 Number类型 因为我这数据是用分页处理 若是 使用index,会有重复的id,会导致在缩放地图时 有些 marker 消失,
obj.list.forEach(item => {// console.log(item, 'foreach');this.marker.push({id: Number(item.stationId),iconPath: '/static/images/mapStation.png', //显示的图标title: item.stationName,latitude: Number(item.stationLat),longitude: Number(item.stationLng),width: 30, //宽height: 30, //高callout: { //自定义标记点上方的气泡窗口 点击有效content: '空闲' + item.totalFree, //文本color: '#ffffff', //文字颜色fontSize: 15, //文本大小borderRadius: 15, //边框圆角padding: '10',bgColor: '#406390', //背景颜色display: 'ALWAYS', //常显}})})
后合并obj.list 数组 并赋值
this.mapList = this.mapList.concat(obj.list) (视野范围方法里需要使用 )
async getStationList() {console.log('发送请求前 打印用户经纬度', this.latitude, this.longitude);const {data: {obj,msg,resCode}} = await uni.$http.post('/uniapp/pile/queryStationInfos', {pageSize: this.pageSize,pageNum: this.pageNum,stationLng: this.longitude,stationLat: this.latitude})console.log('queryStationInfos,查询充电站信息列表显示总数据', obj, msg, resCode);if (resCode !== "00100000") return uni.$showMsg()this.total = obj.total// console.log('充电站信息列表 mapList', obj.list);obj.list.forEach(item => {// console.log(item, 'foreach');this.marker.push({id: Number(item.stationId),iconPath: '/static/images/mapStation.png', //显示的图标title: item.stationName,latitude: Number(item.stationLat),longitude: Number(item.stationLng),width: 30, //宽height: 30, //高callout: { //自定义标记点上方的气泡窗口 点击有效content: '空闲' + item.totalFree, //文本color: '#ffffff', //文字颜色fontSize: 15, //文本大小borderRadius: 15, //边框圆角padding: '10',bgColor: '#406390', //背景颜色display: 'ALWAYS', //常显}})})this.mapShow = truethis.mapList = this.mapList.concat(obj.list)console.log(this.marker);// for (let index in this.mapList) {// let stationMarker = {// iconPath: '/static/images/mapStation.png', //显示的图标 // id: Number(index) || 0,// title: this.mapList[index].stationName || '',// latitude: Number(this.mapList[index].stationLat),// longitude: Number(this.mapList[index].stationLng),// width: 30, //宽// height: 30, //高// callout: { //自定义标记点上方的气泡窗口 点击有效// content: '空闲' + this.mapList[index].totalFree, //文本// color: '#ffffff', //文字颜色// fontSize: 15, //文本大小// borderRadius: 15, //边框圆角// padding: '10',// bgColor: '#406390', //背景颜色// display: 'ALWAYS', //常显// }// }// // console.log(stationMarker, 'stationMarker');// this.marker.push(stationMarker)// }}
② regionChange 视野发生变化时 触发 分页逻辑
regionChange() {
this.tag = false
if (this.pageNum * this.pageSize >= this.total) return
this.pageNum++
this.getStationList()
},
③ callouttap 点击气泡时触发 查找 当前 marker id 等于 stationId 的数组
这里要注意下类型的一个转换 e.detail.markerId --> 是 marker id 它是数字类型
而 mapList 里面的 stationId 为 字符串 类型 ,因此这要做个类型转换,若不转换的话,点击所有的 气泡,卡片上面的内容 是显示一样的
callouttap(e) {
let id = String(e.detail.markerId)
// console.log(this.mapList, id);
let arr = this.mapList.find(item => {
return item.stationId === id
})
this.markerIdClick = [arr]
// console.log('点击id', id, '数组', this.markerIdClick);
this.tag = true
},
(4)style样式
/deep/ .uni-searchbar__box-search-input {
color: #fff !important;
}
输入框默认 黑色