Skip to the content.

最近在写外卖的项目,必然逃不过要跟地图组件打交道。 在Vue项目中,一般有外部组件需求的时候,首先会到官方三宝中扒一扒

vue-baidu-map 百度地图

加分:文档较详细好用,使用方便 减分:功能相对较少,不过够用了

vue-amap 高德地图(非官方)

加分:做了基本用法的封装,使代码风格更偏向于Vue,可与原生AMap混用 减分:开发自万能的饿厂,之前用过 element-ui 的同学都晓得其中的苦,文档不够详细,很多用法要自己一遍一遍尝试,出了问题只能到 gayhubIssues [逃.gif]…

amap 高德地图(原生)

加分:只有想不到,没有做不到,基本满足任何PM的变态需求 减分:…

上原生

可能不是最佳实践,但是简单暴力

1. 首先在项目入口文件 index.html 中引入 AMap ,没错只要一行
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width,initial-scale=1.0">
    <meta name="apple-mobile-web-app-capable" content="yes">
    <meta name="apple-mobile-web-app-status-bar-style" content="black"/>
    <title>AMap-demo</title>
    <script type="text/javascript" src="http://webapi.amap.com/maps?v=1.4.2&key=您申请的key值"></script> <!-- 高德地图 -->
  </head>
  <body>
    <div id="app"></div>
  </body>
</html>
2. 在 template 中选定地图的div容器,在 script 中调用地图

Demo: http://lbs.amap.com/api/javascript-api/example/map/map-show

<template>
  <div class="demo-wrap">
    <div id="container" style="width:500px; height:300px"></div>
  </div>
</template>
export default {
  data(){
    return{
    }
  },
  mounted(){
    let map = new AMap.Map('container',{
      zoom: 12,
      center: [116.39,39.9]
    })
  }
}

到这里,不出意外的话地图就出现了。 如果报错了,可能是引入失败,另外没有引入时没有 key 值是不会报错的。 如果没有报错而地图不显示,可能是: 1.没有设置地图容器宽高 2.地图被定位元素遮挡,尝试设置定位属性并提升 z-index 值 3.没有初始化地图,或者初始化地图的方法没有被执行 4.地图显示,但是没有内容只有蓝蓝的一片,恭喜啦可能是你定位到了海里 [雾.gif]…,把 zoom 设置的小一些看下当前位置

3. 组件用例 点标记

正常我们在项目中,可能不会写一堆全丢进 mounted/created 里,把初始化和组件调用写在方法里,在需要的时候调用,方便解耦复用减少重复代码,比如这样: Demo: http://lbs.amap.com/api/javascript-api/example/marker/marker-content

export default {
  data(){
    return{
    }
  },
  mounted(){
    this.zoom = 14
    this.center = [121.59996, 31.197646]
    this.map_ = new AMap.Map("amap-wrap", { //初始化地图
      zoom: this.zoom,
      center: this.center
    })

    this.setMarker('marker1',[121.59997, 31.197647]) //点标记1
    this.setMarker('marker2',[121.59967, 31.197667]) //点标记2
  },
  methods:{
    setMarker(markers,position){ //添加点标记
      this.markers = new AMap.Marker({
        position: position,
        map: this.map_ //把点标记绑在前面初始化的 map_ 上,否则不显示
      })
    },
  }
}
4. 组件用例 点标记模拟位置移动

这里有个比较难受的问题,就是在Vue中,我们习惯在 data(){return{}} 中初始变量,然后在其他地方去赋值操作。这个对于 amap 是不生效的,需要直接用 this 注册在 Vue 实例上,所以当我们需要操作同一个变量的时候,比如改变中心点坐标,或者点标记坐标的时候,就需要清除上一个值,并赋新值。 比如模拟一个点坐标的移动: Demo: http://lbs.amap.com/api/javascript-api/example/marker/replaying-historical-running-data

export default {
  data(){
    return{
    }
  },
  mounted(){
    this.zoom = 14
    this.center = [121.59996, 31.197646]
    this.map_ = new AMap.Map("amap-wrap", { //初始化地图
      zoom: this.zoom,
      center: this.center
    })

    this.setMarker()
  },
  methods:{
    setMarker(){ //添加点标记
      let x = this.center[0]
      let y = this.center[1]

      setInterval(()=>{ //模拟骑手位置移动
        x+=0.0001
        y+=0.0001
        console.log(x,y)
        let marker = new AMap.Marker({ //设置下一个点坐标
          icon : 'https://www.xxx.com/xxx/images/sender_icon.png', //自定义点坐标图片
          position : [x, y],
          map : this.map_
        })
        setInterval(()=>{
          marker.setMap() //置空上一个点坐标
        },2000)
      },2000)
    },
  }
}
5. 组件用例 圆半径范围

Demo: http://lbs.amap.com/api/javascript-api/example/overlayers/polyline-circle-polygon

export default {
  data(){
    return{
    }
  },
  mounted(){
    this.zoom = 14
    this.center = [121.59996, 31.197646]
    this.map_ = new AMap.Map("amap-wrap", { //初始化地图
      zoom: this.zoom,
      center: this.center
    })

    this.setCircle()
  },
  methods:{
    setCircle(){ //添加圆形范围
      this.circle = new AMap.Circle({
        center: this.center,    //圆心位置
        radius: 3000,           //半径
        strokeColor: "#2395ff", //线颜色
        strokeOpacity: .2,      //线透明度
        strokeWeight: 1,        //线粗细度
        fillColor: "#2395ff",   //填充颜色
        fillOpacity: .2,        //填充透明度
        map: this.map_
      })
    },
  }
}
6. 组件用例 定位到当前位置按钮

Demo: http://lbs.amap.com/api/javascript-api/example/location/browser-location

export default {
  data(){
    return{
    }
  },
  mounted(){
    this.zoom = 14
    this.center = [121.59996, 31.197646]
    this.map_ = new AMap.Map("amap-wrap", { //初始化地图
      zoom: this.zoom,
      center: this.center
    })

    this.setGeolocation()
  },
  methods:{
    setGeolocation(){ //添加定位btn
      this.map_.plugin('AMap.Geolocation', ()=>{
        this.geolocation = new AMap.Geolocation({
          enableHighAccuracy: true,             //是否使用高精度定位,默认:true
          timeout: 5000,                        //超过10秒后停止定位,默认:无穷大
          buttonOffset: new AMap.Pixel(10, 10), //定位按钮与设置的停靠位置的偏移量,默认:Pixel(10, 20)
          zoomToAccuracy: true,                 //定位成功后调整地图视野范围使定位位置及精度范围视野内可见,默认:false
          buttonPosition:'RB'
        })
        this.map_.addControl(this.geolocation)
        this.geolocation.getCurrentPosition()
        AMap.event.addListener(this.geolocation, 'complete', (res)=>{console.log(res)}) //定位成功返回值
        AMap.event.addListener(this.geolocation, 'error', (res)=>{console.log(res)})    //定位失败返回值
      })
    },
  }
}
7. 组件用例 点击地图选点

Demo: https://lbs.amap.com/fn/jsdemo_loader/?url=http%3A%2F%2Fwebapi.amap.com%2Fdemos%2Fgeocoder%2Fgeocoder.html

export default {
  data(){
    return{
    }
  },
  mounted(){
    this.zoom = 14
    this.center = [121.59996, 31.197646]
    this.map_ = new AMap.Map("amap-wrap", { //初始化地图
      zoom: this.zoom,
      center: this.center
    })

    this.Geocoder()
  },
  methods:{
    Geocoder(){ //添加定位btn
      this.map_.plugin('AMap.Geocoder',()=>{
        this.geocoder = new AMap.Geocoder({
          city: "010"//城市,默认:“全国”
        });
        this.marker = new AMap.Marker({
          map:this.map_,
          bubble:true
        })
        this.map_.on('click',(e)=>{
          this.marker.setPosition(e.lnglat)
          this.geocoder.getAddress(e.lnglat,(status,result)=>{
            if(status=='complete'){
              let addr_detail = result.regeocode.addressComponent
              this.addr_name = addr_detail.province + addr_detail.city + addr_detail.district + addr_detail.township + addr_detail.street
              console.log(result.regeocode.addressComponent) //选点地址
              console.log([e.lnglat.lng,e.lnglat.lat]) //选点经纬度
            }else{
              console.log('无法获取地址')
            }
          })
        })
      })
    },
  }
}
8. 组件用例 设置多边形范围选区(移动端滑动手势)

Demo: http://lbs.amap.com/others/demo_list/demos/map_drawcust.html Demo code: view-source:http://lbs.amap.com/others/demo_list/demos/map_drawcust.html

export default {
  data(){
    return{
    }
  },
  mounted(){
    this.zoom = 14
    this.center = [121.59996, 31.197646]
    this.map_ = new AMap.Map("amap-wrap", { //初始化地图
      zoom: this.zoom,
      center: this.center
    })

    //通过touchstart和touchmove,捕获手势坐标,连接为多边形的边线
    let _this = this
    let polyline
    let arr = []
    AMap.event.addListener(map_, 'touchstart', function (e) {
      polyline = new AMap.Polyline({
        map: map_,
        path: []
      })
    })

    AMap.event.addListener(map_, 'touchmove', function (e) {
      if (arr.length <= 1) arr.push(e.lnglat)
      let len = arr.length, obj = arr[len - 1]
      if (len >= 1 && (obj.lng !== e.lnglat.lng || obj.lat !== e.lnglat.lat)) arr.push(e.lnglat)
      polyline.setPath(arr)
    })

    AMap.event.addListener(map_, 'touchend', function (e) {
      let polygon = new AMap.Polygon({
        map: map_,
        path: arr
      })
      _this.send_range = arr
      polyline.setMap(null)
      console.log(_this.send_range) //这里可以看到选区的坐标集合的数组
    })
  },
  methods:{
  }
}
9. 组件用例 展示多边形范围选区

Demo: http://lbs.amap.com/api/javascript-api/example/overlayers/polyline-circle-polygon

export default {
  data(){
    return{
    }
  },
  mounted(){
    this.zoom = 14
    this.center = [121.59996, 31.197646]
    this.map_ = new AMap.Map("amap-wrap", { //初始化地图
      zoom: this.zoom,
      center: this.center
    })

    this.setPolygon()
  },
  methods:{
    setPolygon(){ //设置多边形边界路径
      let send_range = [
        [116.403322, 39.920255],
        [116.410703, 39.897555],
        [116.402292, 39.892353],
        [116.389846, 39.891365]
      ]
      this.polygon = new AMap.Polygon({
        path: send_range, //配送范围
        strokeColor: "#2395ff", //线颜色
        strokeOpacity: .2, //线透明度
        strokeWeight: 3, //线宽
        fillColor: "#2395ff", //填充色
        fillOpacity: .35, //填充透明度
        map:this.map_
      })
  }
}

OK 暂时用到的就这么多,打完收工 [逃.gif]…