Vue爬坑之旅(二十五):vue实现百度地图双向位置信息绑定

官方文档:百度地图api SDK

线上demo:https://my.weblf.cn/lf_demo/map/baidu

一、先引入百度地图插件库,可使用多种引入方式,本文采用cdn引入


<script type="text/javascript" src="https://api.map.baidu.com/api?v=2.0&ak=你自己的密钥"></script>

二、使用百度地图,直接在.vue页面中使用(其中city是从网上找的一个中国地区表):

import Vue from 'vue'
import BMap from 'BMap'
import city from './../../../../static/js/city'

三、实现

template:

<template>
  <div class="templeConfigurationEdit">
    <ul>
      <li>
        <p>表单一:</p>
        <el-input placeholder="随便写点啥" v-model="editData.name"></el-input>
      </li>
      <li>
        <p>表单二:</p>
        <div>
          <el-radio v-model="editData.status" :label="1" border size="medium">未合作</el-radio>
          <el-radio v-model="editData.status" :label="2" border size="medium">已合作</el-radio>
        </div>
      </li>
      <li>
        <p>位置:</p>
        <div class="templeConfigurationEdit-map">
          <!-- 根据地区层级表切换地图区域 -->
          <div class="templeConfigurationEdit-map-div">
            <el-select v-model="mapProvince" id="templeConfigurationEdit-1" placeholder="省" @visible-change="visibleChange('templeConfigurationEdit-1')" @change="watchProvince">
              <el-option v-for="(value, key) in mapProvinceList" :key="key" :label="value" :value="key"></el-option>
            </el-select>
            <el-select v-model="mapCity" id="templeConfigurationEdit-2" placeholder="市" @visible-change="visibleChange('templeConfigurationEdit-2')" @change="watchCity">
              <el-option v-for="(value, key) in mapCityList" :key="key" :label="value" :value="key"></el-option>
            </el-select>
            <el-select v-model="mapArea" id="templeConfigurationEdit-3" placeholder="区" @visible-change="visibleChange('templeConfigurationEdit-3')" @change="watchArea">
              <el-option v-for="(value, key) in mapAreaList" :key="key" :label="value" :value="key"></el-option>
            </el-select>
            <el-input placeholder="经度" disabled v-model="editData.longitude"></el-input>
            <el-input placeholder="纬度" disabled v-model="editData.latitude"></el-input>
          </div>
          <!-- 文本搜索框切换地图区域 -->
          <el-input placeholder="请输入要搜索的内容" v-model="editData.address" class="watchAddress"></el-input>
          <!-- 地图显示的位置 -->
          <div id="baiduMap" ref="baiduMap"></div>
        </div>
      </li>
      <li>
        <p>表单三:</p>
        <el-input placeholder="随便写点啥" v-model="editData.abbot"></el-input>
      </li>
      <div class="button-group-right">
        <el-button type="danger" size="small" @click="reset">取消</el-button>
        <el-button type="primary" size="small" @click="determine">确定</el-button>
      </div>
    </ul>
  </div>
</template>

js

<script>
import Vue from 'vue'
import BMap from 'BMap'
import city from './../../../../static/js/city'

export default {
  data () {
    return {
      editData: {
        abbot: '',
        name: '',
        status: 1,
        address: '山西省阳泉市平定县',
        area_id: 140321,
        latitude: '37.791884',
        longitude: '113.633375'
      },
      map: '',
      mapLocal: '',
      mapProvince: '',
      mapProvinceList: [],
      mapCity: '',
      mapCityList: [],
      mapArea: '',
      mapAreaList: []
    }
  },
  props: [],
  mixins: [],
  methods: {
    // 地图初始化
    mapInit (status) {
      let that = this
      // 省市区下拉省初始化赋值
      that.mapProvinceList = city['86']
      // 创建地图实例
      that.map = new BMap.Map('baiduMap')
      // 初始化地图创建
      that.map.centerAndZoom(new BMap.Point(that.editData.longitude || 116.404, that.editData.latitude || 39.915), 11)
      // 进行初始化城市定位
      that.map.setCurrentCity('北京')
      // 开启鼠标滚轮缩放功能,仅对PC上有效
      that.map.enableScrollWheelZoom(true)
      // 启动地图惯性拖拽
      that.map.enableContinuousZoom(true)
      // 将控件(平移缩放控件)添加到地图上
      that.map.addControl(new BMap.NavigationControl(true))
      // 增加地图缩略图
      that.map.addControl(new BMap.OverviewMapControl({isOpen: true}))
      // 创建位置检索、周边检索和范围检索
      that.mapLocal = new BMap.LocalSearch(that.map, { renderOptions: { map: that.map } })
      // 地图位置点击事件
      let geocoder = new BMap.Geocoder()
      that.map.addEventListener('click', (e) => {
        geocoder.getLocation(e.point, function (rs) {
          let addProvince = rs.addressComponents.province
          let addCity = rs.addressComponents.city
          let addDistrict = rs.addressComponents.district

          // 反向遍历省
          for (let p in city['86']) {
            if (addProvince === city['86'][p]) {
              that.mapProvince = p
              that.watchProvince('click')
              break
            }
          }

          // 反向遍历市
          for (let c in city[that.mapProvince]) {
            if (addCity === city[that.mapProvince][c]) {
              that.mapCity = c
              that.watchCity('click')
              break
            }
          }

          // 反向遍历区
          for (let t in city[that.mapCity]) {
            if (addDistrict === city[that.mapCity][t]) {
              that.mapArea = t
              that.watchArea('click')
              break
            }
          }

          that.editData.address = (rs.addressComponents.street + rs.addressComponents.streetNumber) || rs.address
          that.editData.longitude = String(e.point.lng)
          that.editData.latitude = String(e.point.lat)
          that.watchAddress()
        })
      })
      // 进行数据初始化
      if (this.editData.status) { this.dataInit() }
    },
    // 进行数据初始化
    dataInit () {
      let that = this
      that.mapProvince = String(that.editData.area_id).substr(0, 2) + '0000'
      that.watchProvince('click')

      that.mapCity = String(that.editData.area_id).substr(0, 4) + '00'
      that.watchCity('click')

      that.mapArea = String(that.editData.area_id)
      that.watchArea('click')

      Vue.set(that.editData, 'name', that.editData.name)
      Vue.set(that.editData, 'status', that.editData.status)
      Vue.set(that.editData, 'area_id', that.editData.area_id)
      Vue.set(that.editData, 'longitude', that.editData.longitude)
      Vue.set(that.editData, 'latitude', that.editData.latitude)
      Vue.set(that.editData, 'address', that.editData.address)

      that.watchAddress()
    },
    // 提交按钮
    determine () {
      let that = this
      if (!that.editData.longitude || !that.editData.latitude || !that.editData.address || !that.editData.area_id) {
        this.$notify.error({
          title: '错误',
          message: '请选择地址'
        })
      } else {
        console.log(that.editData)
      }
    },
    // 重置按钮
    reset () {
      this.editData = {
        abbot: '',
        name: '',
        status: '',
        address: '',
        area_id: '',
        latitude: '',
        longitude: ''
      }
      this.mapCity = ''
      this.mapArea = ''
      this.editData.address = ''
      this.editData.longitude = ''
      this.editData.latitude = ''
      this.mapCityList = []
      this.mapProvince = ''
      this.mapProvinceList = []
      this.mapAreaList = []
      this.mapInit(true)
    },
    // 重置省级数据,获取省级表
    watchProvince (type) {
      this.mapCity = ''
      this.mapArea = ''
      this.editData.address = ''
      this.editData.longitude = ''
      this.editData.latitude = ''
      this.mapCityList = city[this.mapProvince]
      if (type !== 'click') { this.mapLocal.search(city['86'][this.mapProvince]) }
    },
    // 重置市级数据,获取市级表
    watchCity (type) {
      this.mapArea = ''
      this.editData.address = ''
      this.mapAreaList = city[this.mapCity]
      if (type !== 'click') { this.mapLocal.search(city[this.mapProvince][this.mapCity]) }
    },
    // 重置县级数据,获取县级表
    watchArea (type) {
      this.editData.address = ''
      this.editData.area_id = Number(this.mapArea)
      if (type !== 'click') { this.mapLocal.search(city[this.mapCity][this.mapArea]) }
    },
    // 监听地址搜索框
    watchAddress () {
      let mapProvince = (this.mapProvince ? city['86'][this.mapProvince] : '')
      let mapCity = (this.mapProvince && this.mapCity ? city[this.mapProvince][this.mapCity] : '')
      let mapArea = (this.mapCity && this.mapArea ? city[this.mapCity][this.mapArea] : '')
      let searchName = mapProvince + mapCity + mapArea + this.editData.address
      this.mapLocal.search(searchName)
    },
    // 当选项栏显示时
    visibleChange (n) {
      console.log(n)
    }
  },
  watch: {
    'editData.address' () {
      this.watchAddress()
    }
  },
  async mounted () {
    this.mapInit(true)
  }
}
</script>

scss

.templeConfigurationEdit {
  width: 100%;
  height: auto;

  >ul {
    width: 800px;
    height: auto;
    overflow: hidden;
    margin: 0 auto;

    >li {
      width: 100%;
      height: auto;
      line-height: 40px;
      overflow: hidden;
      margin-bottom: 10px;

      .templeConfigurationEdit-map {
        width: 100%;
        height: auto;
        overflow: hidden;

        .templeConfigurationEdit-map-div {

          .el-select {
            width: 181px !important;
          }

          .is-disabled {
            width: 120px;
          }
        }

        .el-input {
          margin-bottom: 5px;
        }

        #baiduMap {
          height: 400px;
        }
      }

      .upload-img {
        margin-bottom: 0;
      }
    }
  }
}

 效果图:

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章