> 文章列表 > uniapp 之 将marker 渲染在地图上 点击弹层文字时显示当前信息

uniapp 之 将marker 渲染在地图上 点击弹层文字时显示当前信息

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;
  }

输入框默认 黑色

 使用样式穿透 可以改变输入框 输入字体颜色