vue中使用高德地图完成多级联动

写在前面

首先,有一款vue的高德地图插件,vue-amap, 强烈建议不要用。它既没有实现数据的双向绑定,api接口又十分不全,业务需求简单还好,稍微复杂一点就hold不住了,还是直接用原生的高德地图吧。

高德地图文档 http://lbs.amap.com/api/javascript-api/summary/

在vue中处理高德地图,本身是不能双向绑定的,所以vue充当的是一个数据和方法管理的工作。这时候要处理好的几个问题是

  • 1.高德地图的刷新问题
  • 2.层级控制
  • 3.搜索条件的控制
  • 4.数据存储
  • 5.方法归类
  • 6.调取远程数据

初始化

初始化需要在高德地图申请一个key,引入的时候直接加入key: src="//webapi.amap.com/maps?v=1.3&key=对应的key值"

在dom中创建容器,并完成初始化绑定。这里我在data中创建一个空对象,然后直接实例化到这个对象中,方便以后调用

初始化插件可以自定义添加,这里添加了一个toolbar

通过getCity方法,可以获取当前定位的城市。但是问题是只有在服务器上才能用,不然会报错Cannot read property 'addressComponent' of undefined。

   this.map = new AMap.Map('map', {
      resizeEnable: true,
      zoom: this.zoom.zoomInit
   })
    this.map.plugin(["AMap.ToolBar"], function () {
       _this.map.addControl(new AMap.ToolBar())
    })
    this.map.getCity(function(data) {
      if (data['province'] && typeof data['province'] === 'string') {
        console.log('定位', data)
        let name = data.city || data.province
        name = name.replace(/市/g, '')
        _this.setDingweiChengshi(name)
      }
    })
  

高德地图事件

这里我主要用了三个事件,一个是zoomend,层级缩放完成之后出发;一个是moveend,手动拖拽完成后出发;一个是对自定义的marker遮盖物添加点击事件。

  AMap.event.addListener(_this.map, 'zoomend', _this.zoomChange);
  // 绑定moveend改变事件
  AMap.event.addListener(_this.map, 'moveend', _this.moveendChange);

  this.markers = listData.map(item => {
    let marker = new AMap.Marker({
      map: _this.map,
      position: item.zuobiao.split(','),
      offset: new AMap.Pixel(-12, -36),
      content: '
' +item.t_name+ '

' +item.count+ '

', id: item.id, name: item.t_name }) marker.on('click', function(e) { _this.dotClick(e) }) return marker })

逻辑处理

初始化之后,业务需求是要将城市/区域/楼盘三级进行综合展示,并且城市要配合地图的拖动进行切换。当然还有一堆搜索条件的介入,这里暂且不提。

整体思路是

  • 1.将搜索条件进行统一处理,每次都用一个对象去进行搜索,然后要确定好当前层级和当前所处的模式
  • 2.将城市列表/区域列表/楼盘列表各分出各自的数据获取方法/数据渲染方法,并分别甩出入口。搜索时按照确定的当前模式进行搜索
  • 3.地图的moveend方法判断是否切换城市,zoomend方法结束后判断是否需要修改当前所处的模式

这样整体架构是通了,就是比较繁琐的具体操作了。但是最后发现高德地图有一个处理不合理的地方,这里列出来。

首先它提供了一个setFitView方法,这个方法的本意是帮助把当前的markers设置到合适的大小显示在屏幕中。他接受一个参数,就是数组,也就是说如果有五十个数据,只想让前十个分布到合适的屏幕位置中, 只需要将这个arr传入就行了

但是问题来了。首先setFitView是会按照自己的逻辑处理zoom层级的。我们因为要根据zoomend方法监听是否在城市/区域/楼盘之间进行切换,所以,如果你点入到楼盘时,setFitView自动 将zoom层级进入到城市的水平,那么就会紧接着出发zoomend方法进入到之前设定的城市列表,这个问题就卡死了。

主要是他的setFitView并不接受传入zoom层级范围,全凭他自己瞎搞,很是坑爹呀。

放一张小图示例一下,每一个选项都要跟地图联动,所以这个业务逻辑的核心点就是处理好搜索条件

img1

随机浏览