vue[高德地图的vue组件式开发]

地图在常规的vue项目中是一种比较常见的内容,通常我们只需要按照官方的文档示例以及api文档即可满足各种开发的需求,但是官方的文档示例通常都是直接在html文件中展现、js代码也是直接写在script中,然而vue式的开发却需要使用组件的形式,因此在结构上以及相关的方法与内容的定义上是有一定的区别的,因此这里记录vue组件式开发地图的一些常规操作。

引入高德地图

引入方式可以直接参照官方
同步加载:在index.html中加上标签引入,然后在对应的组件中即可使用AMap对象。如:

// 在index.html中放置
<script src="https://webapi.amap.com/maps?v=1.4.15&key=key值"></script>

异步加载:异步的加载方式与官方有点差异,但原理也是一样的。
第一步:建立一个AMap.js文件用于配置异步加载地图,内容为

export default function MapLoader() {
  return new Promise((resolve, reject) => {
    if (window.AMap) {
      resolve(window.AMap);
    } else {
      let script = document.createElement("script");
      script.type = "text/javascript";
      script.async = true;
      script.src = "http://webapi.amap.com/maps?v=1.4.15&callback=onAMapLoaded&key=key值";
      script.onerror = reject;
      document.head.appendChild(script);
    }
    window.onAMapLoaded = () => {
      resolve(window.AMap);
    };
  });
}

第二步:将该文件导入main.js并且在vue原型链上注册该方法

// 挂载高德地图
import MapLoader from "src/utils/AMap.js";
Vue.prototype.$map = MapLoader;

第三步:在对应的.vue组件中使用,注意在mounted生命周期中创建并使用该方法

mounted() {
    this.$map().then(AMap => {
      let map = new AMap.Map("login-box", {
        center: [117.000923, 36.675807]
      });
    });
  }

通常情况下同步加载的第一次加载速度是比较慢的,因此如果项目中仅仅只有几个地方使用地图,建议使用异步加载,但如果项目中比较多的使用地图且项目带宽允许的情况下,可以使用同步加载。

补充:加载地图插件

插件的加载形式。
同步加载:直接在标签的src后面加上&plugin=xxx即可。如:

<script src="https://webapi.amap.com/maps?v=1.4.15&key=key值&plugin=AMap.ControlBar"></script>

然后在对应的组件中即可:new AMap.ControlBar()之类的

异步加载方式一:通过AMap.plugin()这个方法来加载,第一个参数为一个插件数组,第二个为回调函数。

  this.$map().then(AMap => {
      let map = new AMap.Map("login-box", {
        center: [117.000923, 36.675807],
        zoom: 11
      });
      AMap.plugin(['AMap.ControlBar'],() => {
        let controlbar= new AMap.ControlBar();
        map.addControl(controlbar);
      });
    });

异步加载方式二:在之前的AMap.js中的script.src连接后面直接使用&plugin=xxx即可,这种其实就是插件的同步加载方式,只是地图的异步加载的而已。

script.src = "http://webapi.amap.com/maps?v=1.4.15&callback=onAMapLoaded&key=key值&plugin=AMap.ControlBar";

使用:直接new即可

   this.$map().then(AMap => {
      let map = new AMap.Map("login-box", {
        center: [117.000923, 36.675807],
        zoom: 11
      });
      let controlbar= new AMap.ControlBar();
      map.addControl(controlbar);
    });
组件内的使用建议

vue组件形式的交互方式与原生js中的交互方式是有许多差异的。总结几点:

第一点:但凡使用new关键字创建出来的实例对象,建议在data中定义一个变量用于保存,如:
<template>
  <div class="login-box" id="login-box"></div>
</template>
<script>
export default {
  data() {
    return {
      map: {}, // 保存地图对象
      toolbar: {} // 保存controlBar对象-这是一个地图插件
    };
  },
  methods: {},
  mounted() {
    this.map = new AMap.Map("login-box", {
       center: [117.000923, 36.675807],
       zoom: 11
     });
    this.toolbar = new AMap.ControlBar();
    this.map.addControl(this.toolbar);
  }
};
</script>

这样的好处就是本组件内都可以直接通过this来获取到需要的实例内容,方便做操作

第二点:但凡需要同时创建多个实例对象的内容,建议在data中创建一个数组保存,并且定义一个识别数组,在push实例对象的时候同时push一个唯一识别内容进去,方便后续从实例对象数组中寻找。

代码示例:

<template>
  <div class="login-box" id="login-box"></div>
</template>
<script>
export default {
  data() {
    return {
      map: {},
      markers: [], // 保存多个点标记的内容的数组
      markersData: [] // 保存点标记对应的唯一标记,用于寻找点标记
    };
  },
  methods: {
    // 当页面执行了某个操作的时候,触发了clickMarker。需要达到效果如:让该标号对应的点标记亮起来
    clickMarker(row){
      // row是某个操作后列表的详情值,里面有单个内容的id
      // 找出这个id在markersData中的标号。
      let index = this.markersData.findIndex(item => {
        return row.id == item; 
      });
      // 这个就是该id对应起来的点标记,然后就可以操作了。-原因是markers和markersData中的下标是一一对应的
      this.markers[index].setIcon('xxx');
    }
  },
  mounted() {
   this.map = new AMap.Map("login-box", {
      center: [117.000923, 36.675807],
      zoom: 11
    });
    // 通过接口获取到一个数据列表后,需要将其上的内容都标记在地图上。
    /* 数据格式:
        [
          {id: '1',lng: 128.15643,lat: 165.45632},
          {id: '2',lng: 128.15643,lat: 165.45632},
          {id: '3',lng: 128.15643,lat: 165.45632}
        ]
      */
    getList().then(res => {
      if (res) {
        for (let i = 0; i < res.length; i++) {
          // 每次循环创建一个点标记
          let marker = new AMap.Marker({});
          // 设置内容后将点标记渲染到地图上
          marker.setPisition([res.lng, res.lat]);
          this.map.add(marker);
          // 保存点标记
          this.markers.push(marker);
          // 保存点标记唯一标号-作用在后面
          this.markersData.push(res.id);
        }
      }
    });
  }
};
</script>
第三点:建议将地图要素的要素创建过程都独立封装成方法,这样可以让组件结构内容变得更加的清晰。
<template>
  <div class="login-box" id="login-box"></div>
</template>
<script>
export default {
  data() {
    return {
      map: {},
      markers: [] // 保存多个点标记的内容的数组
    };
  },
  methods: {
  	// 创建地图
    createMap() {
      this.map = new AMap.map('xx',{
        center: [117.000923, 36.675807],
        zoom: 11
        //......
      });
    },
    // 创建点标记
    createMarker(arr){
      let marker = new AMap.marker({
        icon: arr.icon,
        position: [arr.lng,arr.lat]
        //......
      });
      marker.on('click',()=>{
		// xxxxx
	  })
      return marker;
    },
    // 清除地图上的所有内容
    clearMap() {
      this.map.clearMap();
    },
  },
  mounted() {
    this.createMap();
    this.markers.push(this.createMarker(arr));
  }
};
</script>

参照高德地图的示例以及api足以完成地图相关的开发内容,项目示例与vue之间的转换本质是一样的,区别仅仅只是形式不同而已。
vue[高德地图自定义InfoWindow弹出框中事件问题]

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值