柯大侠教你vue2.0如何完整接入高德地图,实现经纬度和详细地址之间丝滑切换

493 阅读3分钟

详细步骤如下:

高德开放平台: lbs.amap.com/

  • 1.引入vue-amap
npm i vue-amap
  • 2.在main入口文件中配置
import VueAMap from 'vue-amap' // 引入高德地图
Vue.use(VueAMap)
VueAMap.initAMapApiLoader({
  key: 'xxxxxxxx', // 高德地图申请的key
  plugin: [ // 这里根据自己项目按需引入插件
    'AMap.Autocomplete',
    'AMap.PlaceSearch',
    'AMap.Scale',
    'AMap.OverView',
    'AMap.ToolBar',
    'AMap.MapType',
    'AMap.PolyEditor',
    'AMap.CircleEditor', // 圆形编辑器插件
    'AMap.Geolocation', // 定位控件,用来获取和展示用户主机所在的经纬度位置
    'AMap.Geocoder', // 地理编码与逆地理编码服务,用于地址描述与坐标间的相互转换
    'AMap.CitySearch'
  ]
})
window._AMapSecurityConfig = {
  securityJsCode: 'yyyyyyyyyyy' // 搞德地图申请的密钥
}

// 1.解决高德地图刷新显示不出来
const amapKeys = Object.keys(localStorage).filter(key => key.match(/^_AMap_/))
amapKeys.forEach(key => { localStorage.removeItem(key) })

// 2.注意
  坑位请注意:在高德开放平台注册完账号后,创建自己的应用后,需要添加key,这时候切记添加的key类型是web端,web端,web端,重要事情重复三遍,如果是web服务那就不行了。
  

完整代码

1.封装了一个map组件,map.vue

 <template>
  <div class="map-container">
    <div class="amap-page-container">
      <van-search v-model="address" placeholder="请输入详细地址" @search="handleSearchMap" />
      <el-amap vid="amap" :plugin="plugin" class="amap-demo" :center="center" :zoom="zoom" :events='events'>
        <!-- 点击显示标记 -->
        <el-amap-marker v-for="(marker, index) in markers" :key="marker.index" :position="marker.position"
          :icon="marker.icon" :title="marker.title" :events="marker.events" :visible="marker.visible"
          :draggable="marker.draggable" :vid="index"></el-amap-marker>
      </el-amap>
      <div class="lngLatAddress">
        <div class="address">
          <span>详细位置:</span>
          <span>{{ this.mapInfo.address }}</span>
        </div>
        <div class="lnglat lng">
          <span>经度:</span>
          <span>{{ this.mapInfo.lng }}</span>
        </div>
        <div class="lnglat">
          <span>纬度:</span>
          <span>{{ this.mapInfo.lat }}</span>
        </div>
      </div>
    </div>
  </div>
</template>

<script>
import { Toast } from 'vant'
export default {
  props: ['Nowlnglat'],
  data () {
    const _this = this
    return {
      address: '', // 详细地址查询
      mapInfo: {
        address: '',
        lng: '',
        lat: ''
      },
      // 地图相关
      zoom: 13, // 地图缩放
      center: [117.139632, 31.835295], // 初始中心-创新产业园二期
      loaded: false,
      markers: [], // 点击显示的标记默认的定位
      //  自动定位到当前位置
      plugin: [
        {
          timeout: 1000, // 超过10秒后停止定位
          panToLocation: true, // 定位成功后将定位到的位置作为地图中心点
          zoomToAccuracy: true, // 定位成功后调整地图视野范围使定位位置及精度范围视野内可见
          enableHighAccuracy: true, // 高精度定位
          pName: 'Geolocation',
          events: {
            init (o) {
              // o 是高德地图定位插件实例
              o.getCurrentPosition((status, result) => {
                if (result && result.position) {
                  this.mapInfo.address = result.formattedAddress
                  this.mapInfo.lng = result.position.lng
                  this.mapInfo.lat = result.position.lat
                  if (this.Nowlnglat[0] != null && this.Nowlnglat[1] != null) {
                    const Clnglat = this.Nowlnglat
                    this.center = Clnglat
                    this.markers = [{ position: Clnglat }]
                    // eslint-disable-next-line no-undef
                    const geocoder = new AMap.Geocoder({ radius: 1000 })
                    // 根据坐标获取位置  将经纬度 转换后成 地址信息 放在 输入框展示
                    geocoder.getAddress(Clnglat, function (status, result) {
                      if (status === 'complete' && result.info === 'OK') {
                        this.mapInfo.address = result.regeocode.formattedAddress
                        this.mapInfo.lng = this.Nowlnglat[0]
                        this.mapInfo.lat = this.Nowlnglat[1]
                      }
                    })
                  } else {
                    this.center = [this.mapInfo.lng, this.mapInfo.lat]
                    this.markers = [{ position: this.center }]
                  }
                  this.loaded = true
                  this.$emit('mapDing', this.mapInfo)
                } else {
                  o.getCityInfo((status, result) => {
                    if (result && result.center) {
                      _this.mapInfo.address = result.province + result.city
                      _this.mapInfo.lng = result.center[0]
                      _this.mapInfo.lat = result.center[1]
                      if (_this.Nowlnglat[0] != null && _this.Nowlnglat[1] != null) {
                        const Clnglat = _this.Nowlnglat
                        _this.center = Clnglat
                        _this.markers = [{ position: Clnglat }]
                        // eslint-disable-next-line no-undef
                        const geocoder = new AMap.Geocoder({ radius: 1000 })
                        // 根据坐标获取位置  将经纬度 转换后成 地址信息 放在 输入框展示
                        geocoder.getAddress(Clnglat, function (status, result) {
                          if (status === 'complete' && result.info === 'OK') {
                            _this.mapInfo.address = result.regeocode.formattedAddress
                            _this.mapInfo.lng = _this.Nowlnglat[0]
                            _this.mapInfo.lat = _this.Nowlnglat[1]
                          }
                        })
                      } else {
                        _this.center = result.center
                        _this.markers = [{ position: _this.center }]
                      }
                      _this.loaded = true
                      _this.$emit('mapDing', _this.mapInfo)
                    }
                  })
                }
              })
            }
          }
        }
      ],
      // 点击地图获取当前位置并显示标记
      events: {
        click (e) {
          _this.handleSearchAddress(e.lnglat)
        },
        dragend: (e) => {
          const index = this.markers.length
          _this.dragend(e, index)
        }
      }
    }
  },
  methods: {
    // 拖拽地图
    dragend (e, index) {
      console.log('e', e, index)
    },
    // 1.根据详细地址查询地图的经纬度
    handleSearchMap () {
      const _this = this
      // eslint-disable-next-line no-undef
      const geocoder = new AMap.Geocoder({
        city: '' // 城市设为北京,默认:“全国”
      })
      geocoder.getLocation(this.address, function (status, result) {
        if (status === 'complete' && result.geocodes.length) {
          console.log('result-查询', result)
          const data = result.geocodes[0]
          _this.mapInfo.address = data.formattedAddress
          _this.mapInfo.lng = data.location.lng
          _this.mapInfo.lat = data.location.lat
          _this.center = [_this.mapInfo.lng, _this.mapInfo.lat]
          _this.loaded = true
          _this.markers = [{ position: _this.center }]
        } else {
          Toast('根据地址查询位置失败')
        }
      })
    },
    // 2.根据经纬度查询详细地址
    handleSearchAddress (e) {
      // console.log('点击位置e', e)
      const { lng, lat } = e
      this.mapInfo.lng = lng
      this.mapInfo.lat = lat
      this.center = [lng, lat]
      this.loaded = true
      this.markers = [{ position: this.center }]
      this.getDetailAddress()
      this.$emit('mapDing', this.mapInfo)
    },
    handelQuery () {
      this.mapInfo.lng = parseFloat(this.mapInfo.lng)
      this.mapInfo.lat = parseFloat(this.mapInfo.lat)
      this.center = [parseFloat(this.mapInfo.lng), parseFloat(this.mapInfo.lat)]
      this.loaded = true
      this.markers = [{
        position: this.center
      }]
      this.getDetailAddress()
      this.$emit('mapDing', this.mapInfo)
    },
    // 调用高德地图getAddress方法获取详细地址
    getDetailAddress () {
      const _this = this
      // eslint-disable-next-line no-undef
      const geocoder = new AMap.Geocoder({
        radius: 1000 // 范围,默认:500
      })
      const lnglat = [this.mapInfo.lng, this.mapInfo.lat]
      // console.log('根据经纬度查询lnglat', lnglat)
      geocoder.getAddress(lnglat, function (status, result) {
        if (status === 'complete' && result.regeocode) {
          _this.mapInfo.address = result.regeocode.formattedAddress
        } else {
          _this.mapInfo = {}
          Toast('根据经纬度查询地址失败')
        }
      })
    }
  }
}
</script>

<style lang="scss" scoped>
.map-container{
  height: 100%;
  width: 100%;
  padding: 10px;
  display: flex;
  justify-content: center;
  .amap-page-container {
    height: 100%;
    width: 100%;
    position: relative;
    .lngLatAddress {
      margin-top: 15px;
      .address {
        font-size: 12px;
        font-family: PingFang SC;
        font-weight: 400;
        color: #000;
      }
      .lnglat {
        font-size: 12px;
        font-family: PingFang SC;
        font-weight: 400;
        color: #505050;
      }
      .lng {
        margin: 5px 0;
      }
    }
    .el-vue-amap-container {
      height: 208px;
    }
  }
}
</style>

2.父组件调用

<template>
    <div class="map">
      <amap ref="amap" @mapDing="getCoordinate" :Nowlnglat="Nowlnglat"></amap>
    </div>
</template>
<script>
import amap from './components/map'
import { Toast } from 'vant'

export default {
  components: {
    amap
  },
  data () {
    return {
      mapInfo: {},
      Nowlnglat: [], // 经纬度传值
      lng: 117.139632,
      lat: 31.835295
    }
  },
  async mounted () {
    this.openMap()
  },
  methods: { 
    openMap () {
      if (this.lng && this.lat) {
        this.Nowlnglat = [this.lng, this.lat]
      }
    },
    getCoordinate (map) {
      this.mapInfo = map
      this.Nowlnglat = [map?.lng, map?.lat]
    }
  }
}
</script>

3.技术总结

 1、其实接入没什么难度,日常用插件步骤铁铁们都知道,容易踩坑的就是添加key一定要是web端才可以,不能是web服务。
 2、特别批注:需要配置安全秘钥,自20211202升级,所申请的key必须和安全密钥 securityJsCode一起使用。