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

组件

<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

posted @ 2020-12-21 16:04  冬冬先生  阅读(8601)  评论(1编辑  收藏  举报