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

 效果圖:

 

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