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 = false
        if (this.pageNum * this.pageSize >= this.total) return
        this.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.total
        obj.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 = true
        this.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)

补充 动态style 也可以改为  :style="{'margin-top':topHeight+'px'}"

 <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 = true
        this.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;
  }

输入框默认 黑色

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

  • 2
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
uniapp中使用高德地图marker点击事件,可以通过以下步骤实现: 1. 首先,在uniapp的页面中引入高德地图组件,可以使用官方提供的`uni-amap`插件。 2. 在页面中添加地图组件,并设置相应的属性,如id、latitude、longitude等。 3. 在页面的methods中定义marker点击事件函数。可以使用`bindmarkertap`属性绑定一个点击事件,当marker点击,会触发相应的函数。 4. 在marker点击事件函数中,可以编写需要执行的代码逻辑。例如,可以在点击事件中跳转到其它页面,或者显示相应的信息。 以下是一个示例代码: ``` <template> <view> <uni-amap :amap-id="'myMap'" :amap-style="'width: 100%; height: 400rpx;'"></uni-amap> </view> </template> <script> const eventType = { // 定义marker点击事件的类型 MARKER_TAP: 'markertap' } export default { data() { return { markers: [ { id: 1, title: 'Marker 1', latitude: 39.99, longitude: 116.32 }, { id: 2, title: 'Marker 2', latitude: 40.01, longitude: 116.34 } ] } }, methods: { onMarkerTap(e) { // 获取被点击marker的id const markerId = e.markerId // 在这里可以编写点击事件的逻辑,例如跳转到其它页面或显示相应信息 console.log('Marker ' + markerId + ' has been tapped') } }, onReady() { uni.$emit(eventType.MARKER_TAP, this.onMarkerTap) } } </script> ``` 以上代码在页面加载,通过`onReady`钩子函数监听marker点击事件。当marker点击,会触发`onMarkerTap`函数,并输出被点击marker的id。你可以在该函数中根据需要编写相应的业务逻辑。请注意,本示例仅作为参考,具体实现可能会根据需求有所变化。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值