利用Vue-amap实现基于高德地图定位(搜索、地图选址)

时间:2024-02-18 13:38:02

组件

<template>
  <div
    class="amap-page-container"
    style="height: 400px; margin-bottom: 200px; background: #ccc"
  >
    <el-amap-search-box
      class="search-box"
      :search-option="searchOption"
      :on-search-result="onSearchResult"
    ></el-amap-search-box>
    <el-amap
      vid="amapDemo"
      :center="center"
      :zoom="zoom"
      class="amap-demo"
      :plugin="plugin"
      :events="events"
    >
      <el-amap-marker
        v-for="(marker, index) in markers"
        :position="marker"
        :key="\'marker\' + index"
      ></el-amap-marker>
    </el-amap>
    <div class="toolbar" v-if="loaded">
      position: [{{ lng }}, {{ lat }}] address: {{ address }}
    </div>
    <div v-else>正在定位</div>
  </div>
</template>

  <style scoped>
.search-box {
  position: absolute;
  top: 25px;
  left: 20px;
}

.amap-page-container {
  position: relative;
}
</style>

  <script>
module.exports = {
  data: function () {
    let self = this

    return {
      markers: [
        [121.59996, 31.197646],
        [121.40018, 31.197622],
        [121.69991, 31.207649]
      ],
      searchOption: {
        city: \'杭州\',
        citylimit: false
      },
      zoom: 12,
      loaded: false,
      center: [121.59996, 31.197646],
      plugin: [
        {
          pName: \'Geolocation\',
          events: {
            init(o) {
              // o 是高德地图定位插件实例
              o.getCurrentPosition((status, result) => {
                if (result && result.position) {
                  self.lng = result.position.lng
                  self.lat = result.position.lat
                  self.center = [self.lng, self.lat]
                  self.address = result.formattedAddress
                  self.loaded = true
                  self.$nextTick()
                }
              })
            }
          }
        }
      ],
      address: \'\',
      events: {
        click(e) {
          let { lng, lat } = e.lnglat
          self.lng = lng
          self.lat = lat

          // 这里通过高德 SDK 完成。
          var geocoder = new AMap.Geocoder({
            radius: 1000,
            extensions: \'all\'
          })
          geocoder.getAddress([lng, lat], function (status, result) {
            if (status === \'complete\' && result.info === \'OK\') {
              if (result && result.regeocode) {
                self.address = result.regeocode.formattedAddress
                self.$nextTick()
              }
            }
          })
        }
      },
      lng: 0,
      lat: 0
    }
  },
  methods: {
    addMarker: function () {
      let lng = 121.5 + Math.round(Math.random() * 1000) / 10000
      let lat = 31.197646 + Math.round(Math.random() * 500) / 10000
      this.markers.push([lng, lat])
    },
    onSearchResult(pois) {
      let latSum = 0
      let lngSum = 0
      if (pois.length > 0) {
        pois.forEach(poi => {
          let { lng, lat } = poi
          lngSum += lng
          latSum += lat
          this.markers.push([poi.lng, poi.lat])
        })
        let mapcenter = {
          lng: lngSum / pois.length,
          lat: latSum / pois.length
        }
        this.center = [mapcenter.lng, mapcenter.lat]
      }
    }
  },
  watch: {
    address: {
      handler: function (val, oldVal) {
        this.address = val
        this.$emit(\'sendAddress\', this.address)
      },
      // 深度观察监听
      deep: true
    }
  }
}
</script>

main.js的配置文件

import Vue from \'vue\'
import \'normalize.css/normalize.css\' // A modern alternative to CSS resets
import Element from \'element-ui\'
import AMap from \'vue-amap\'
import \'element-ui/lib/theme-chalk/index.css\'
import \'@/styles/index.scss\'
import App from \'./App\'
import store from \'./store\'
import router from \'./router\'
import \'./icons\'
import \'./errorLog\'
import \'./permission\'
import imgPicker from \'./components/ImgPicker\'
import MpTable from \'./components/MpTable\'
import FooterBottom from \'./components/FooterBottom\'
import PaginationComponent from \'./components/PaginationComponent\'
import DateRange from \'./components/DateRange\'
import bfapp from \'./utils/app.js\'
import directives from \'./directive/permission/index\' // 注册滚动条加载触发事件v-loadmore绑定

// 富文本
import \'../static/UE/ueditor.config.js\'
import \'../static/UE/ueditor.all.min.js\'
import \'../static/UE/lang/zh-cn/zh-cn.js\'
import \'../static/UE/ueditor.parse.min.js\'
import \'../static/UE/themes/default/css/ueditor.css\'

Vue.component(\'imgPicker\', imgPicker)
Vue.component(\'MpTable\', MpTable)
Vue.component(\'FooterBottom\', FooterBottom)
Vue.component(\'PaginationComponent\', PaginationComponent)
Vue.component(\'DateRange\', DateRange)

import * as filters from \'./filters\'

// import roles from \'@/directive/permission/index.js\'

Vue.use(Element, {
  size: \'medium\' // set element-ui default size
})
Vue.use(directives)
Vue.use(AMap)
// 初始化vue-amap
AMap.initAMapApiLoader({
  // 高德key
  key: \'16017152a3418aaa3824f2c1d723374d\',
  // 插件集合 (插件按需引入)
  // plugin: [\'AMap.Geolocation\', \'AMap.Autocomplete\', \'AMap.PlaceSearch\']
  plugin: [
    \'AMap.Geocoder\',
    \'AMap.Autocomplete\', // 输入提示插件
    \'AMap.PlaceSearch\', // POI搜索插件
    \'AMap.Scale\', // 右下角缩略图插件 比例尺
    \'AMap.OverView\', // 地图鹰眼插件
    \'AMap.ToolBar\', // 地图工具条
    \'AMap.MapType\', // 类别切换控件,实现默认图层与卫星图、实施交通图层之间切换的控制
    \'AMap.PolyEditor\', // 编辑 折线多,边形
    \'AMap.CircleEditor\', // 圆形编辑器插件
    \'AMap.Geolocation\' // 定位控件,用来获取和展示用户主机所在的经纬度位置
  ]
})

Object.keys(filters).forEach(key => {
  Vue.filter(key, filters[key])
})

Vue.config.productionTip = false

Vue.prototype.$app = bfapp

/* eslint-disable no-new */
const app = new Vue({
  el: \'#app\',
  router,
  store,
  components: {
    App
  },
  template: \'<App/>\'
})

export {
  app
}

父组件接收的是最终选择的地址

参考文档:https://elemefe.github.io/vue-amap/#/zh-cn/plugins/geolocation