vue中引入高德地图实现定位功能

责编:menVScode 2020-10-10 13:13 阅读(105)

某次项目开发中,需要实现在web端实现定位功能。即实现在web端搜索定位的功能。首先看一下效果如下:

在这里插入图片描述

功能也相对不是很难,就是需要调用调用地图插件来完成页面地图的加载与显示,本来是打算选取某度的地图,偶然发现高德地图的api也很详细,所以来尝试一下。闲话少说,看具体实现。


1. 首先申请一个高德地图的开发平台秘钥
这个秘钥在我们调用高德地图的api中需要使用到,所以必须要申请一个。申请方式搜索高德地图,进入官网,注册一个账号,在控制台里可以看到申请开发秘钥功能。


2. 建立Index.vue文件
在Index.vue中放入以下代码,主要设置的是地图布局的样式。

<div class="col-md-12" style="text-align: center;padding-top: 50px"  v-if="placeSearch">
    <label for="location">找到我们:</label>
    <input type="text" name="location" style="width: 300px;border-radius: 6px" v-model="keyWord"/>
    <button class="btn-danger" name="search" style="border-radius: 6px" @click="handleSearch">搜索</button>
</div>
<div class="row col-md-12" style="padding-top: 30px">
    <div id="searchResult" class="col-md-3"></div>
    <div id="mapContainer" class="col-md-6" style="height: 500px;" >正在加载数据 ...</div>
</div>

UI框架选择了bootstrap,所以上面选用的是栅格布局。


3. 引入vue-amap
(1) 如果是利用vue-cli搭建的工程,首先利用npm方式安装vue-amap。安装代码如下所示:

npm install vue-amap --save

如果不是利用脚手架搭建,只是单页面应用程序,可以通过cdn方式引入:

<script src="https://unpkg.com/vue-amap/dist/index.js"></script>

(2) 若是利用vue-cli搭建工程,安装完vue-amap之后,入口文件main.js中记得调用,代码如下:

Vue.use(AMap);


4. 新建mapConfig.js文件,用来放置申请的秘钥等相关变量参数,因为我的功能还需要在指定城市搜索,所以定义了一个mapCityName来存储城市名,具体文件内容如下:

// 高德地图 key
export const MapKey = '申请的高德秘钥'
// 地图限定城市
export const MapCityName = '杭州'


5. 同时我们还需要创建一个函数来动态生成script的标签,创建remoteLoad.js文件。内容如下:

export default function remoteLoad (url, hasCallback) {
  return createScript(url)
  /**
   * 创建script
   * @param url
   * @returns {Promise}
   */
  function createScript (url) {
    let scriptElement = document.createElement('script')
    document.body.appendChild(scriptElement)
    let promise = new Promise((resolve, reject) => {
      scriptElement.addEventListener('load', e => {
        removeScript(scriptElement)
        if (!hasCallback) {
          resolve(e)
        }
      }, false)

      scriptElement.addEventListener('error', e => {
        removeScript(scriptElement)
        reject(e)
      }, false)

      if (hasCallback) {
        window.____callback____ = function () {
          resolve()
          window.____callback____ = null
        }
      }
    })

    if (hasCallback) {
      url += '&callback=____callback____'
    }

    scriptElement.src = url

    return promise
  }

  /**
   * 移除script标签
   * @param scriptElement script dom
   */
  function removeScript (scriptElement) {
    document.body.removeChild(scriptElement)
  }
}


6. 在Index.vue中的调用及methods方法如下所示:

 <template>
    <div>
    <div class="col-md-12" style="text-align: center;padding-top: 50px"  v-if="placeSearch">
        <label for="location">找到我们:</label>
        <input type="text" name="location" style="width: 300px;border-radius: 6px" v-model="keyWord"/>
        <button class="btn-danger" name="search" style="border-radius: 6px" @click="handleSearch">搜索</button>
     </div>
          <div class="row col-md-12" style="padding-top: 30px">
          <div id="searchResult" class="col-md-3"></div>
          <div id="mapContainer" class="col-md-6" style="height: 500px;" >正在加载数据 ...</div>
     </div>
 </div>
 </template>
<script type="text/ecmascript-6">
  import remoteLoad from '@/utils/remoteLoad'
  import { MapKey, MapCityName } from '@/config/mapConfig'
  export default {
    props: ['lat', 'lng'],
    data () {
      return {
        keyWord: '阿里巴巴商学院',
        placeSearch: null,
        dragStatus: false,
        AMapUI: null,
        AMap: null,
      }
    },
    methods: {
      // 搜索
      handleSearch () {
        if (this.keyWord) {
          this.placeSearch.search(this.keyWord)
      },
      // 实例化地图
      initMap () {
        // 加载PositionPicker,loadUI的路径参数为模块名中 'ui/' 之后的部分
        let AMapUI = this.AMapUI = window.AMapUI
        let AMap = this.AMap = window.AMap
        AMapUI.loadUI(['misc/PositionPicker'], PositionPicker => {
          let mapConfig = {
            zoom: 16,
            cityName: MapCityName
          }
          if (this.lat && this.lng) {
            mapConfig.center = [this.lng, this.lat]
          }
          let map = new AMap.Map('mapContainer', mapConfig)
          // 加载地图搜索插件
          AMap.service('AMap.PlaceSearch', () => {
            this.placeSearch = new AMap.PlaceSearch({
              pageSize: 5,
              pageIndex: 1,
              citylimit: true,
              city: MapCityName,
              map: map,
              panel: 'searchResult'
            })
          })
          // 启用工具条
          AMap.plugin(['AMap.ToolBar'], function () {
            map.addControl(new AMap.ToolBar({
              position: 'RB'
            }))
          })
          // 创建地图拖拽
          let positionPicker = new PositionPicker({
            mode: 'dragMap', // 设定为拖拽地图模式,可选'dragMap'、'dragMarker',默认为'dragMap'
            map: map // 依赖地图对象
          })
          // 拖拽完成发送自定义 drag 事件
          positionPicker.on('success', positionResult => {
            // 过滤掉初始化地图后的第一次默认拖放
            if (!this.dragStatus) {
              this.dragStatus = true
            } else {
              this.$emit('drag', positionResult)
            }
          })
          // 启动拖放
          positionPicker.start()
        })
      }
    },
    async created () {
      // 已载入高德地图API,则直接初始化地图
      if (window.AMap && window.AMapUI) {
        this.initMap()
        // 未载入高德地图API,则先载入API再初始化
      } else {
        await remoteLoad(`http://webapi.amap.com/maps?v=1.3&key=${MapKey}`)
        await remoteLoad('http://webapi.amap.com/ui/1.0/main.js')
        this.initMap()
      }
    }
  }
</script>

至此,关键文件都已完成,具体功能也已实现。本文参考http://www.rxshc.com/140.html实现,感谢作者分享,如有不足,恳请批评指正。

标签: 高德地图 vue
前端交流群: MVC前端网(menvscode.com)-qq交流群:551903636

邮箱快速注册

忘记密码