当我们在使用百度地图时,多页面还好,与文档的demo比较契合,但是当在vue中使用百度地图时,会遇到各种坑,遇到各种限制,不厌其烦。从而,选择vue-baidu-map插件就比较切合vue项目,此插件为在百度地图基础上封装的组件,进行数据双向绑定,从而让我们比较专注于功能的实现。

添加自定义控件以及地图定位,搜索地址请看文章:https://blog.csdn.net/qq_39009348/article/details/105990473

官网地址:https://dafrok.github.io/vue-baidu-map/#/zh/map/baidu-map

安装:

npm install vue-baidu-map --save

全局注册:

import Vue from 'vue'
import BaiduMap from 'vue-baidu-map'

Vue.use(BaiduMap, {
  // ak 是在百度地图开发者平台申请的密钥 详见 http://lbsyun.baidu.com/apiconsole/key */
  ak: 'YOUR_APP_KEY'
})

使用:

<template>
  <baidu-map class="bm-view">
  </baidu-map>
</template>

<style>
.bm-view {
  width: 100%;
  height: 300px;
}
</style>

我们在地图上实现一个拥有比列尺,缩放控件,搜索城市,动态添加点坐标,覆盖物信息窗口,点聚合等功能

<template>
<div id="mapPage">
    <P class="commomLoading" style="display:none"></P>
    <div class="mapbox" id="mapbox">
      <baidu-map id="map" :zoom="map.zoom" :center="{lng: map.center.lng, lat: map.center.lat}" @ready="handler" :scroll-wheel-zoom="true">
          <!--比例尺控件-->
          <bm-scale anchor="BMAP_ANCHOR_TOP_LEFT"></bm-scale>
          <!-- 定位控件 ,无效-->
          <bm-geolocation anchor="BMAP_ANCHOR_TOP_LEFT" :showAddressBar="true" :autoLocation="true"></bm-geolocation>
          <!--缩放控件-->
          <bm-navigation anchor="BMAP_ANCHOR_TOP_LEFT" ></bm-navigation>
          <!-- 搜索城市 -->
          <bm-city-list anchor="BMAP_ANCHOR_TOP_RIGHT"></bm-city-list>
          <!--集中器聚合动态添加的点坐标-->
          <bm-marker-clusterer :averageCenter="true" :maxZoom="16">
              <bm-marker v-for="Cmarker of Cmarkers" :key="Cmarker.id" :position="{lng: Cmarker.longitude, lat: Cmarker.latitude}" @click="lookDetail(Cmarker)">
                <bm-label :content="Cmarker.name" title="Hover me" :labelStyle="{color: 'red', fontSize : '14px'}" :offset="{width: -25, height: -25}"/>
                <bm-context-menu>
                  <bm-context-menu-item :callback="getPosition" text="获取坐标"></bm-context-menu-item>
                </bm-context-menu>
              </bm-marker>
          </bm-marker-clusterer>
          <bm-info-window :width="550" :height="270" :position="{lng: infoWindow.info.longitude, lat: infoWindow.info.latitude}" title="集中器信息" :show="infoWindow.show" @close="infoWindowClose" @open="infoWindowOpen">
            <div class="infoTitle">
              <P class="infoHeader">设备信息栏:</P>
              <el-row>
                <el-col :span="10"><div class="info-content">名称:{{infoWindow.info.name}}</div></el-col>
                <el-col :span="6"><div class="info-content">类型:{{infoWindow.info.terminalType}}</div></el-col>
                <el-col :span="6"><div class="info-content">经度:{{infoWindow.info.longitude}}</div></el-col>
              </el-row>
              <el-row style="margin-top:6px">
                <el-col :span="8"><div class="info-content">纬度:{{infoWindow.info.latitude}}</div></el-col>
              </el-row>
              <P class="infoHeader">设备操作栏:</P>
                <el-col :span="6"><el-button :plain="true" type="info" size="mini" :disabled="readIsDisabled" @click="handleDataUpload(infoWindow.info.id, infoWindow.info.comid)">读取时间</el-button></el-col>
            </div>
          </bm-info-window>
          <!--灯具聚合动态添加的点坐标-->
          <bm-marker-clusterer :averageCenter="true" :maxZoom="16">
            <bm-marker v-for="Lampmarker of Lampmarkers" :key="Lampmarker.latitude" :position="{lng: Lampmarker.longitude, lat: Lampmarker.latitude}" @click="lookLampDetail(Lampmarker)">
                <bm-label :content="Lampmarker.name" title="Hover me" :labelStyle="{color: 'red', fontSize : '14px'}" :offset="{width: -25, height: -25}"/>
                <bm-context-menu>
                  <bm-context-menu-item :callback="getPosition" text="获取坐标"></bm-context-menu-item>
                </bm-context-menu>
            </bm-marker>
          </bm-marker-clusterer>
      </baidu-map>
      <!-- 弹出层部分 -->
      <!-- 读取时间表弹出层 -->
      <el-dialog title="时间表信息" :append-to-body="true" :visible.sync="timeTableVisible" :close-on-click-modal="false">
        <template v-for="(item, index) in timeTableInfo">
          <el-row type="flex" :gutter="80" :key="index">
            <el-col class="commonstyle">
              <span>{{item.left}}</span>
            </el-col>
            <el-col class="commonstyle">
              <span>{{item.right}}</span>
            </el-col>
          </el-row>
        </template>
        <div slot="footer" class="dialog-footer">
          <el-button @click.native="timeTableVisible=false" type="primary">退出</el-button>
        </div>
      </el-dialog>
  </div>
  </div>
</template>

<script>
import controllerIcon from './asset/controle.png'
import lampicon from './asset/roadLamp.png'
import locationIcon from './asset/location.png'
import Qs from 'qs'
// 百度地图
import BmScale from 'vue-baidu-map/components/controls/Scale'
import BmGeolocation from 'vue-baidu-map/components/controls/Geolocation'
import BmNavigation from 'vue-baidu-map/components/controls/Navigation'
import BmMarkerClusterer from 'vue-baidu-map/components/extra/MarkerClusterer'
import BmMarker from 'vue-baidu-map/components/overlays/Marker'
import BmInfoWindow from 'vue-baidu-map/components/overlays/InfoWindow'
import {
  getCMarked,
  getLampMarked,
  doSend,
  doSend2
} from './apis/index.js'
export default {
  components: {
    BmScale,
    BmGeolocation,
    BmNavigation,
    BmMarkerClusterer,
    BmMarker,
    BmInfoWindow
  },
  data() {
    return {
      locationIcon1: locationIcon,
      map: {
        center: { lng: 108.93, lat: 34.27 }, // '西安市',
        zoom: 12
      },
      markers: [], // 灯具已标注数组
      Cmarkers: [], // 集中器地图标注数组
      infoWindow: { // 集中器信息窗口
        show: false,
        info: {
          latitude: '',
          longitude: '',
          id: ''
        }
      },
      controllerIcon: controllerIcon, // 集中器图标
      // 灯具信息窗口
      lampicon: lampicon, // 灯具图标
      Lampmarkers: [], // 已标注的灯具数组
      LampinfoWindow: { // 灯具信息窗口
        show: false,
        info: {
          comid: '',
          groupID: -1,
          id: -1,
          ismark: true,
          latitude: '',
          longitude: '',
          name: '',
          tcomid: ''
        }
      },
      // 集中器读取时钟
      readIsDisabled: false, // 读取是否禁用
      readAllTime1: Object, // 读取定时器
      readTimeNum: 0, // 读取定时器计数
    }
  },
  created() {
  },
  mounted() {
  },
  methods: {
    /** 加载地图及标注设备部分 */
    // 地图初始化
    handler({ BMap, map }) {
      console.log(BMap, map)
      // this.map.center.lng = 118.802422
      // this.map.center.lat = 32.065631
      // this.map.zoom = 12;
      // this.map.width= document.getElementById("container").clientWidth-330+'px'
      // this.map.height=document.body.clientHeight -160+'px'
      this.getCMarked()
      this.getLampMarke()
      this.getCoverMarke()
      this.getSmokeMarke()
      this.getDisMarke()
    },
    // 获取已经标注集中器经纬度数组
    getCMarked() {
      getCMarked().then(res => {
        if (res.rows.length > 0 || res.rows !== undefined) {
          var cArr = []
          for (var i = 0; i < res.rows.length; i++) {
            if (res.rows[i].ismark) {
              cArr.push(res.rows[i])
            }
          }
          console.log('集中器数据', cArr)
          this.Cmarkers = cArr
        } else {
          this.$message({
            message: '获取数据失败',
            type: 'error'
          })
        }
      })
    },
    // 获取已经标注灯具经纬度数组
    getLampMarke() {
      getLampMarked().then(res => {
        if (res.rows.length > 0 || res.rows !== undefined) {
          var LampArr = []
          for (var i = 0; i < res.rows.length; i++) {
            if (res.rows[i].ismark) {
              LampArr.push(res.rows[i])
            }
          }
          this.Lampmarkers = LampArr
        } else {
          this.$message({
            message: '获取数据失败',
            type: 'error'
          })
        }
      })
    },
    // 查看集中器详情
    lookDetail(data, target) {
      console.log('data', data)
      this.infoWindow.show = true
      this.infoWindow.info = data
      this.activeName = '集中器信息'
      var that = this
      // 为弹窗口标题添加title
      this.$nextTick(() => {
        var win = document.querySelector('.BMap_bubble_title')
        win.title = that.activeName
      })
      // if (target === 'left') { // 点击的是左侧列表项,则不需要滚动
      //   this.map.center = { lng: data.lng, lat: data.lat }
      //   this.map.zoom = 15
      //   return
      // }
      // // 滚动到指定元素位置
      // this.$nextTick(() => {
      //   var obj = document.querySelector('.active')
      //   var scrollTop = obj.offsetTop
      //   this.$refs.box.scrollTop = scrollTop - 180
      // })
    },
    // 打开信息窗口
    infoWindowClose(e) {
      this.infoWindow.show = false
    },
    // 关闭集中器信息窗口
    infoWindowOpen(e) {
      this.infoWindow.show = true
    },
    // 查看灯具详情
    lookLampDetail(data) {
      this.LampinfoWindow.show = true
      this.LampinfoWindow.info = data
      console.log('灯具详情', this.LampinfoWindow)
    },
    // 打开灯具信息窗口
    LampinfoWindowClose(e) {
      this.LampinfoWindow.show = false
    },
    // 关闭灯具信息窗口
    LampinfoWindowOpen(e) {
      this.LampinfoWindow.show = true
    },
    /** 设备操作部分 */
    // 点击集中器读取时钟
    handleDataUpload(id, comid) {
      this.$confirm('确认读取吗?', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      })
        .then(() => {
          this.readIsDisabled = false
          var operation = 'readtime'
          this.readGetCommandid(id, comid, operation)
        })
        .catch(() => { })
    },
    // 集中器读取时钟获取commandid
    readGetCommandid(id, comid, operation) {
      var para = {
        operation: operation,
        id: id,
        comid: comid
      }
      var that = this
      var params = Qs.stringify(para)
      doSend(params).then(res => {
        // 若token过期
        if (res.code !== -10) {
          if (res.commandid !== '') {
          // 开启定时器,过了2*20=40秒后关闭定时器,读取超时
            this.readAllTime1 = setInterval(function() {
              that.readTimeNum++ // 定时器计数
              that.readAllSend(res.commandid)
            }, 2000)
          } else {
            this.$message({
              message: '读取失败',
              type: 'info'
            })
          }
        } else {
          clearInterval(this.readAllTime1)
        }
      })
    },
    // 集中器读取时钟获取返回状态
    readAllSend(commandid) {
      var para = {
        commandid: commandid
      }
      var params = Qs.stringify(para)
      doSend2(params).then(res => {
        // 如果token过期
        if (res.code !== -10) {
          if (this.readTimeNum > 20) {
            clearInterval(this.readAllTime1)
            this.readTimeNum = 0
            this.readIsDisabled = false
            this.$message({
              showClose: true,
              message: '读取超时!',
              type: 'info'
            })
          } else {
            if (res.code === 1) {
              // 清除定时器,计数器归零,按钮可点击
              clearInterval(this.readAllTime1)
              this.readTimeNum = 0
              this.readIsDisabled = false
              this.$message({
                showClose: true,
                message: res.mesg,
                type: 'info'
              })
            }
          }
        } else {
          clearInterval(this.readAllTime1)
        }
      })
    },
   
    /** 右键操作部分 */
    getPosition(e) {
      alert(`${e.point.lng} / ${e.point.lat}`)
    }
  }
}
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped lang="scss">
#mapbox {
  width: 100%;
  height: 100%;
  margin: 0;
  padding: 0;
  overflow: hidden;
}
#map {
    width: 100%;
    height: 100%;
    margin: 0;
    font-family: "微软雅黑";
    position: absolute;
  }
  // 交采信息详情
  .commonstyle {
    margin-bottom: 8px;
  }
.infoTitle{
  margin-top:0;
  border-top:1px solid #eeeeee;
  .infoHeader{
    font-size: 14px;
    color:#666;
    border-bottom:1px solid #eeeeee;
  }
  .info-content{
    font-size: 14px;
    color:#666;
  }
}

</style>

 

 效果图:

 

Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐