讲真,写下这个题目的时候,再想想自己整个实现功能的这1天时间,觉得自己好牛逼,啊哈哈哈,吹牛时间到了,进入正题……

    本文从以下几个方面进行阐述。

  • 1. 首先说一下业务需求是什么。
  • 2. 然后说一下解决思路。
  • 3. 最后是实现方式。

    业务需求描述:

    给客户做了一个物资管理系统,前台用的是vue+element-ui。因客户的物资大多是没有定位模块的,但又希望在地图上展示物资。因不能从定位模块获取经纬度数据进而在地图上进行展示,就只能自己手动操作,对物资进行位置设定,然后再在地图上进行展示。具体业务需求为:

    当用户选中某条或某几条物资数据时,点击“设置定位”按钮,就会弹出一个弹出框,弹出框中会展示百度地图及一个“确定”按钮和一个“取消”按钮,当单击地图时,会在地图上进行位置标注。若位置标注完成,用户点击“确定”按钮即可对所需物资进行位置设置,若点击“取消”按钮,则不进行位置设置。

    解决思路:

    好了,业务需求如上所述。针对业务需求,需提出解决思路。

    首先想到的是,在页面中写一个div容器的dialog以备存放地图,并给该div设置一个id,例如id="allmap",然后在js中通过var map = new BMap.Map("allmap");创建地图实例,再通过map.centerAndZoom(new BMap.Point(116.404, 39.915), 11);设置地图中心点及地图展示级别即可。

    这样实现时有一个问题:第一次点击“设置定位”按钮打开弹出框时,弹出框中并没有展示地图;第二次及后面点击按钮打开弹出框时,才会有地图展示出来。

    这是因为,在页面打开时,弹出框并没有被页面加载,所以其id并不存在于页面的DOM树中,当第一次点击按钮打开弹出框时,通过var map = new BMap.Map("allmap");创建地图实例时并不能获取到allmap这个id代表的容器,所以地图第一次并不能展示。但第一次打开弹出框后,dialog中的allmap div已被页面加载过一次,所以第二次再通过var map = new BMap.Map("allmap");创建地图实例时,能够获取到allmap,进而就能够创建成功,所以地图能被展示。

    为解决这个问题,经过调研,发现Vue Baidu Map可直接将center和zoom属性写进<baidu-map>标签中,如下所示:

<baidu-map :center="center" :zoom="zoom" @ready="handler"></baidu-map>

    这样一来就不需要先加载某个容器id再在此id容器中创建地图实例了,就解决了第一次点击按钮打开弹出框时不显示地图的问题了。

    具体实现代码如下图所示:


vue element 创建弹窗组件_业务需求

点击弹出框打开百度地图

    需要注意的是,添加控件时,需要注册控件对应的组件,如下图所示:


vue element 创建弹窗组件_vue element 创建弹窗组件_02

注册控件组件

具体实现代码我直接贴出,就不再描述了。

methods: {
    // 当选择项发生变化时会触发该事件
    handleSelectionChange(val) {
      var i = 0, valLen = val.length;

      if (valLen == 0) {
        this.locData.ids = 0;
      } else {
        for (i; i < valLen; i++) {
          if (i == 0) {
            this.locData.ids = val[i].id;
          } else if (i > 0) {
            this.locData.ids += "," + val[i].id;
          }
        }
      }
    },

    // 当某一行被点击时会触发该事件   参数:row, event, column
    getRowData(editEqu, event, column) {
      this.$refs.equTable.toggleRowSelection(editEqu);
    },

    // 设置定位弹出框
    setLoc(formName) {
      if (this.locData.ids == 0) {
        this.$message({
          message: '请选中装备后再设置定位',
          type: 'warning'
        });
      } else {
        this.locDialog = true;
        map.clearOverlays();
      }
    },
    // 百度地图
    mapReady ({BMap, map}) {
      this.center.lng = 116.404;
      this.center.lat = 39.915;
      this.zoom = 15;
      window.map = map;   //将map变量存储在全局
    },
    // 地图点击事件
    getClickInfo (e) {
      map.clearOverlays();
      var myMarker = new BMap.Marker(new BMap.Point(e.point.lng, e.point.lat));
      map.addOverlay(myMarker);
      this.locData.longitude = e.point.lng;
      this.locData.latitude = e.point.lat;
    },
    // 设置定位确认
    locSubmit(formName) {
      if (this.locData.longitude == "") {
        addOper.$message({
          message: '请单击地图设置定位后再提交',
          type: 'warning'
        });
      } else {
        //  向后台提交locData数据
      }
      this.locDialog = false;
    },
    // 设置定位取消
    locCancle(formName) {
      map.clearOverlays();
      this.locDialog = false;
    }
  }

    这样就实现了所需的功能。最后贴一下实现功能时遇到的问题列表,供各位参考。


vue element 创建弹窗组件_弹出框_03

实现功能过程中的问题列表

    methods里面的方法是根据也无需求写的,大家可参考。有任何问题留言给我哈。谢谢大家!

    最后贴一个超实用链接:Vue Baidu Map