美团官网之腾讯地图组件的创建

686 阅读3分钟

导语

前段时间学习vue,学习过程中通过仿写美团官网对所学知识进行巩固。但由于时间有限,只写了两个界面。现在,为了使项目更加完善,准备再次开工干起来💪!而在开干之前,先复习下之前写的内容。此文则是记录下美团官网商铺页面地图组件的创建过程。

地图组件介绍

首先地图分为小地图和大地图两种,小地图里面包含了一个自定义标注和一个打开大地图的控制按钮,大地图则包含一个地址信息窗口和一个关闭按钮。这里,我们先上两张效果图,明确下最终目标:

图1

图2

小地图

自定义标注

腾讯位置服务平台/JavaScriptAPI有提供一个自定义标注图标的方法,而这里通过自定义Overlay,实现初始化时动态添加标注元素。那么,我们先自定义一个Overlay类:

function CustomOverlay(position) {
    this.position = position;
}

然后,在初始化时重写CustomOverlay的构造方法,同时实现draw接口来绘制和更新自定义的dom元素,实现destroy接口来删除自定义的Dom元素。

initCustomOverlay() {
  var self = this;
  CustomOverlay.prototype = new qq.maps.Overlay()
  CustomOverlay.prototype.construct = function() {
    var map_overlay = this.overlay = document.createElement("div")
    map_overlay.className = 'map-overlay'
    var map_poi_outer = this.div = document.createElement("div")
    map_poi_outer.classList.add('map-poi-outer')
    map_poi_outer.classList.add('init')
    var map_pin = document.createElement("div")
    map_pin.className = 'map-pin' // 
    var map_num = document.createElement("div")
    map_num.className = 'map-num'
    var span = document.createElement('span')
    map_num.appendChild(span)
    map_poi_outer.appendChild(map_pin)
    map_poi_outer.appendChild(map_num)
    this.overlay.appendChild(map_poi_outer)

    //将dom添加到覆盖物层
    var panes = this.getPanes();
    //设置panes的层级,overlayMouseTarget可接收点击事件
    panes.overlayMouseTarget.appendChild(map_overlay);

    this.div.onclick = function() {
        self.openBigMap()
    }
  }
  //draw接口
  CustomOverlay.prototype.draw = function() {
      var overlayProjection = this.getProjection();
      //返回覆盖物容器的相对像素坐标
      var pixel = overlayProjection.fromLatLngToDivPixel(this.position);
      var divStyle = this.div.style;
      divStyle.zIndex = 100
      divStyle.left = pixel.x - 10 + "px"; // 偏差
      divStyle.top = pixel.y - 25 + "px";
  }
  //destroy接口,此方法会在setMap(null)后被调用
  CustomOverlay.prototype.destroy = function() {
      this.div.onclick = null;
      this.div.parentNode.removeChild(this.overlay);
      this.div = null
  }
  return CustomOverlay
}

接着,创建覆盖物。

createOverlays(map) {
  var Overlay = this.CustomOverlay
  var overlay = new Overlay(this.myLatlng);
  overlay.setMap(map);
  // overlay.setMap(null) //删除标注
}

大地图打开按钮

控制按钮也可以自定义,写好之后将他加入地图实例某方位的controls即可。

addZoomCtrl(map) {
  var customZoomDiv = document.createElement('div');
    customZoomDiv.className = 'map-zoomin';
    var iconZoom = document.createElement('i');
    iconZoom.classList.add('iconfont');
    iconZoom.classList.add('icon-zoom_icon');
    customZoomDiv.appendChild(iconZoom);
    customZoomDiv.index = 1; 
    
    // 放置于右下角
    map.controls[qq.maps.ControlPosition.BOTTOM_RIGHT].push(customZoomDiv);
    qq.maps.event.addDomListener(customZoomDiv, 'click', () => {
      this.openBigMap();
  });
}

大地图

地址窗口

此地址窗口可以通过qq.map.InfoWindow实现

createInfoWin(map) {
  return new qq.maps.InfoWindow({
    map: map,
    zIndex: 1,
    visible: false
  });
}

里面的内容则可以自定义,通过infoWin.setContent()设置infowindow的内容

getInfoContent() {
  return `<div class="info-win">\n            
    <p class="poi-name">${this.name || '-'}</p>\n            
    <p class="poi-address ellipsis">${this.address || '-'}</p>\n            
    <p class="poi-phone ellipsis">${this.phone || '-'}</p>\n            
    <p><a href="//map.qq.com/?type=nav&tocoord=${this.lng + ',' + this.lat}&c=${this.lng + ',' + this.lat}&l=13" 
      target="_blank" gaevent="map/view/queryroute">公交/驾车路线查询»</a></p>\n        
    </div>`
}

然后,我们通过infoWin.setPosition()设置一下他在地图上的位置。这样,我们只需要通过infoWin.open()在打开大地图时展示infowindow就可以了。
好了,这次的地图使用就先记录到此了,如果文章对您有帮助,请给小编您的星。具体的代码可见我的Github☞
ps: 1. 美团vue 2. 美团后台