vue中高德地图api的使用,初始化地图并将其组件化

624 阅读1分钟

1.  先 安装  

npm install vue-amap --save

2.  在main.js中引入 下载的地图插件

import VueAMap from 'vue-amap';
Vue.use(VueAMap);VueAMap.initAMapApiLoader({
  key: '2c9d59fc06dxxxxxxxxxxxxxxxxxxx', // 高德地图key
  plugin: [
    'AMap.Scale',       // 地图比例尺插件
    'AMap.OverView',    // 地图鹰眼插件,默认在地图右下角显示缩略图
    'AMap.ToolBar',     // 地图工具条插件,可以用来控制地图的缩放和平移
    'AMap.MapType',     // 地图类型切换插件,用来切换固定的几个常用图层
    'AMap.PlaceSearch', // 输入提示插件
    'AMap.Geolocation', // 定位插件,整合了浏览器定位、精确IP定位、sdk辅助定位多种手段
    'AMap.Geocoder',    // 地址编码服务(地理编码和逆地理编码)
  ], 
  v: '1.4.4',           //  高德SDK的版本
  uiVersion: '1.0',     //  UI库的版本
});

3. 在 子组件中 gdMap.vue 里面调用

<template>
  <el-dialog    
    :close-on-click-modal="false"
    :close-on-press-escape="false"
    style="padding-top: 35vh"
    :visible.sync="visible"
    v-if="visible">
    <template>
      <div class="container">
        <div class="closed">
          <span>添加打卡范围</span>
          <i style="float: right" class="el-icon-close" @click="closeGd"></i>
        </div>        
        <div class="search-box">
          <input v-model="searchKey" type="search" id="search">
          <button @click="searchByHand">搜索</button>
          <div class="tip-box" id="searchTip"></div>
        </div>
        <!-- amap-manager: 地图管理对象
          vid:地图容器节点的ID
          zooms: 地图显示的缩放级别范围,在PC上,默认范围[3,18],取值范围[3-18];在移动设备上,默认范围[3-19],取值范围[3-19]
          center: 地图中心点坐标值
          plugin:地图使用的插件
          events: 事件        -->
        <el-amap class="amap-box"
          :amap-manager="amapManager"
          :vid="'amap-vue'"
          :zoom="zoom"
          :plugin="plugin"               
          :center="center" 
          :events="events">
          <el-amap-circle 
            v-for="(circle,index) in circles"
            :key="index"
             <!-- center 圆心位置  -->
            :center="circle.center"
              <!-- center 圆半径  -->
            :radius="circle.radius"
              <!-- fillColor 圆形填充颜色  -->            :fill-color="circle.fillColor"
              <!-- fillOpacity 圆形填充透明度,取值范围[0,1],0表示完全透明,1表示不透明。默认为0.9  -->
            :fill-opacity="circle.fillOpacity"
              <!-- strokeWeight 轮廓线宽度  -->            :stroke-weight="circle.strokeWeight"
             <!-- strokeColor 设置线条颜色  -->
            :stroke-color="circle.strokeColor"
            :events="circle.events">
          </el-amap-circle>        
        </el-amap>
        <div class="footer">
          <span class="preservation" @click="preservation">确认</span>
          <span class="cancel" @click="cancel">取消</span>
        </div>      
      </div>
    </template>
  </el-dialog>
</template>
<script>
import {AMapManager, lazyAMapApiLoaderInstance} from 'vue-amap'
let amapManager = new AMapManager()
export default {  
name: 'gdAmap',
  props: {    
    text: {
      type: String,
      default: ''
    },
    visible: { 
     type: Boolean,
      default: false,
    },
    range: {
      type: String,
      default: '',
    },
  },
  watch: {
    range(val) {
      this.circles[0].radius = val    
    }  
  },
  data () {
    let self = this
    return { 
      active: false,
      address: null,
      searchKey: '',
      amapManager, 
      markers: [],
      circles: [
        {
          center: [118.78, 32.07],
          radius: 100,
          fillOpacity: 0.2,
          fillColor:'#2587F6',
          strokeWeight: 1,
          strokeColor: '#2587F6',
          events: {
            click(e){
              self.markers = [] 
              let {lng, lat} = e.lnglat
              self.lng = lng
              self.lat = lat
              self.center = [lng, lat]
              self.circles[0].center = [lng, lat]
              self.markers.push([lng, lat])
              // 这里通过高德 SDK 完成。 
             let geocoder = new AMap.Geocoder({
                radius: self.range,
                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.searchKey = result.regeocode.formattedAddress 
                   self.$nextTick()
                  }
                }
              })
            }
          }
        }
      ],
      searchOption: {
        city: '全国',
        citylimit: true
      },
      radius: 100,
      center: [118.78, 32.07],
      zoom: 17,
      lng: 0,
      lat: 0,
      loaded: false,
      events: {
        init () {
          lazyAMapApiLoaderInstance.load().then(() => {
            self.initSearch()
          })
        },
        // 点击获取地址的数据
        click (e) {
          self.markers = []
          let {lng, lat} = e.lnglat
          self.lng = lng
          self.lat = lat
          self.center = [lng, lat]
          self.circles[0].center = [lng, lat]
          self.markers.push([lng, lat])
          // 这里通过高德 SDK 完成。
          let geocoder = new AMap.Geocoder({
            radius: self.range,
            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.searchKey = result.regeocode.formattedAddress
                self.$nextTick()
              }
            }
          })
        }
      },
      // 一些工具插件
      plugin: [
        {
          pName: 'Geocoder',
          events: {
            init (o) {
            }          
          }
        },
        {
          // 默认定位
          pName: 'Geolocation',
          events: {
            init (o) {
              // o是高德地图定位插件实例
              o.getCurrentPosition((status, result) => {
                if (result && result.position) {
                  // 获取地点名称
                  self.address = result.formattedAddress
                  self.searchKey = result.formattedAddress
                  // 设置经度
                  self.lng = result.position.lng
                  // 设置维度
                  self.lat = result.position.lat
                  // 设置坐标
                  self.center = [self.lng, self.lat]
                  self.circles[0].center = [self.lng, self.lat]
                  self.markers.push([self.lng, self.lat])
                  // load
                  self.loaded = true
                  // 页面渲染好后
                  // self.$nextTick()
                }
              })
            }
          }
        },
        {
          // 工具栏
          pName: 'ToolBar',
          events: {
            init (instance) {
            }
          }
        },
        {
          // 鹰眼--小地图
          pName: 'OverView',
          events: {
            init (instance) {
            }
          }
        },
        {
          // 搜索
          pName: 'PlaceSearch',
          events: {
            init (instance) {
            }
          }
        }
      ]
    }
  },
    methods: {
    // 关闭
    closeGd () {
      this.$emit('update:visible', false);
    },
    // 确认
    preservation () {
      this.$emit('address', this.searchKey)
      this.$emit('position', this.circles[0].center)
      this.$emit('update:visible', false);
    },
    // 取消
    cancel () {
      this.$emit('update:visible', false);
    },
    initSearch () {
      let vm = this
      let map = this.amapManager.getMap()
      AMapUI.loadUI(['misc/PoiPicker'],
 function (PoiPicker) {
        var poiPicker = new PoiPicker({
          input: 'search',
          placeSearchOptions: {
            map: map,
            pageSize: 10
          },
          suggestContainer: 'searchTip',
          searchResultsContainer: 'searchTip'
        })
        vm.poiPicker = poiPicker
        // 监听poi选中信息
        poiPicker.on('poiPicked', function (poiResult) {
          let source = poiResult.source
          let poi = poiResult.item
          if (source !== 'search') {
            poiPicker.searchByKeyword(poi.name)
          } else {
            poiPicker.clearSearchResults()
            vm.markers = []
            let lng = poi.location.lng
            let lat = poi.location.lat
            let address = poi.cityname + poi.adname + poi.name
            vm.center = [lng, lat]
            vm.markers.push([lng, lat]) 
            vm.lng = lng
            vm.lat = lat
            vm.address = address
            vm.searchKey = address
            vm.circles[0].center = [lng, lat]
          }
        })
      })
    },
    searchByHand () {
      if (this.searchKey !== '') {
        this.poiPicker.searchByKeyword(this.searchKey)
      }
    }
  }
}
</script>
<style scoped lang="scss">
  .el-dialog__wrapper /deep/ {    .el-dialog {      width: 699px;    }  }  .container {    width: 700px;    height: 500px;    position: absolute;    left: 50%;    top: 50%;    transform: translate3d(-50%, -50%, 0);    /*border: 1px solid #999;*/  }  .closed {    position: absolute;    top: -35px;    z-index: 999999;    cursor: pointer;    width: 100%;    padding: 10px 10px;    background: #e9e9e9;    border-radius: 5px 5px 0 0;    border: 1px solid #999;    border-bottom: 0;    color: #333333;  }  .search-box {    position: absolute;    z-index: 5;    width: 70%;    left: 13%;    top: 15px;    height: 30px;  }  .search-box input {    float: left;    width: 80%;    height: 100%;    border: 1px solid #30ccc1;    padding: 0 8px;    outline: none;  }  .search-box button {    float: left;    width: 20%;    height: 100%;    background: #30ccc1;    border: 1px solid #30ccc1;    color: #fff;    outline: none;  }  .amap-box {    border: solid 1px #999;    border-top: 0;  }  .footer /deep/ {    background: #e9e9e9;    width: 100%;    position: absolute;    padding: 14px 20px;    bottom: -44px;    border: 1px solid #999;    border-top: 0;    border-radius: 0 0 5px 5px;    font-size: 14px;    text-align: right;    .preservation {      padding: 5px 14px;      background: #2587f6;      border-radius: 3px;      color: #ffffff;      margin: 0 10px;      cursor: pointer;    }    .cancel {      margin: 0 10px;      cursor: pointer;      color: rgba(0, 0, 0, 0.65);    }  }  .tip-box {    width: 100%;    max-height: 260px;    position: absolute;    top: 30px;    overflow-y: auto;    background-color: #fff;  }
</style>

4.  在父组件中调用 gdMap.vue 子组件

<template>
<div>
<el-input style="width: 350px"
 disabled
 v-model="region"
 placeholder="请定位打卡位置">
</el-input>
<span class="position" @click="positionAddress">定位</span><iMap  @address="address"
  @position="positions"
  :visible.sync="isShow"
  :text="region"
  :range="range">
</iMap></div></template>
<script>
import iMap from './gdAmap.vue';
export default {
  name: 'addAttendance',
  components: { iMap},
  data() {
    return {
      isShow: false,
      region: '', // 当前位置的文字
      regionPosition: {  lng: '',  lat: '',}, // 经纬度lng,lat
      range: '100', // 范围
   }
  },
  methods: {
    // 从组件中获取地理位置并放在input框里
    address(val) {  this.ruleForm.region = val;},
    // 从组件中获取 经纬度
    positions(val) {
      this.ruleForm.regionPosition = {
      lng: val[0],
      lat: val[1],
       };
     }, 
    // 打开地图组件
    positionAddress() { this.isShow = true;},
   } }
</script>

5.  在esLintrc.js 中引用globals

module.exports = {
  globals: {
    AMap: false,
    AMapUI: false,
  },
};

6. 效果演示

   6.1  父组件 

   6.2  点击定位按钮,子组件地图展示 

       

6.3 点击确认后 传回给父组件