vue 高德地图 异步引入AMap与AMapUI组件

一. 介绍

什么是异步加载:异步加载是和同步加载相对的组件加载方式。同步加载模式又称阻塞模式,在页面加载到该组件时会阻止浏览器的后续处理与后续解析,只有当前加载完成后才会进行下一步的操作。异步加载相反,异步加载模式又称非阻塞加载模式,浏览器在加载js的同时还会进行后续的页面加载。异步加载的方式通常有三种,此次我们主要采用动态创建script标签的方式异步引入高德API。
近期在做服务器定位的项目,有用到高德组件,但是高德地图比较大,同步引入的话导致页面加载变慢,此外,我的项目也不是单页面应用,还涉及到很多其他业务,异步引入高德API就比较有必要。
异步加载指的是为 JS API 指定加载的回调函数,在 JS API 的主体资源加载完毕之后,将自动调用该回调函数。回调函数应该声明在 JS API 入口文件引用之前,异步加载可以减少对其他脚本执行的阻塞。

二. 异步加载AMap组件

新创建一个aMap.js文件,一般会创建一个plugin文件夹,把这个js文件放到plugin文件夹下。这个文件只加载了AMap组件,需要AMapUI组件的去下一个。
项目目录
封装了js文件,之后在需要加载地图的页面直接import就可以,这里还用到了一些Promise的知识(Promise 对象代表了未来将要发生的事件,用来传递异步操作的消息),不清楚的朋友百度看看。

aMap.js

/*
 * 异步创建script标签
 */
export default function MapLoader (key) {
  return new Promise((resolve, reject) => {
    if (window.AMap) {
      resolve(window.AMap)
    } else {
      var script = document.createElement('script')
      const key= '填你申请的key'
      script.type = 'text/javascript'
      script.async = true
      script.src = 'http://webapi.amap.com/maps?v=1.3&callback=initAMap&key=' + key
      script.onerror = reject
      document.head.appendChild(script)
    }
    window.initAMap = () => {
      resolve(window.AMap)
    }
  })
}

在需要加载组件的.vue文件中,在script标签中
import MapLoader from '@/plugin/aMap'

之后在mounted或者created中加载:


    MapLoader().then(AMap => {

      console.log('地图加载成功')
      this.map = new AMap.Map("container", {
        zoom: 17,
        resizeEnable: true
      })
      // ....你的操作
    }, e => {
      console.log('地图加载失败' ,e)
    })

三. 异步加载AMap和AMapUI组件

同时加载AMap组件和AMapUI组件
aMapUI.js:

/*
 * 异步创建script标签
 */
export default function MapUILoader (key) {
  const mp = new Promise((resolve, reject) => {
    if (window.AMap) {
      resolve(window.AMap)
    } else {
      var script = document.createElement('script')
      const key= '填你申请的api'
      script.type = 'text/javascript'
      script.async = true
      script.src = 'http://webapi.amap.com/maps?v=1.3&callback=initAMap&key=' + key
      script.onerror = reject
      document.head.appendChild(script)
    }
    window.initAMap = () => {
      resolve(window.AMap)
    }
  })

  const mpUI = new Promise((resolve, reject) => {
    if (window.AMapUI) {
      resolve(window.AMapUI)
    } else {
      var scriptUI = document.createElement('script')
      scriptUI.type = 'text/javascript'
      scriptUI.src = 'http://webapi.amap.com/ui/1.1/main.js?v=1.1.1'
      scriptUI.onerror = reject

      scriptUI.onload = function(su){
        resolve(window.AMapUI)
      };
      document.head.appendChild(scriptUI)
    }

  })

  return Promise.all([mp,mpUI])
    .then(function (result) {
      return result
    }).catch(e=>{
      console.log(e);})
}

需要加载组件的.vue文件,在created函数中加载:


 MapUILoader().then(AMap => {
      console.log("异步加载组件")
    })
    

由于两个API加载都比较慢,有时候可能会出现AMapUI not defined这样的错误,我们需要延时加载1秒:

 if (!window.AMapUI || !window.AMap){
      // 延时加载
      console.log("延时加载中")
      setTimeout(() => {
        // ...你的操作
      }, 1000)
    }
    else{
      //...你的操作
    }

注:在项目的在这里插入图片描述
文件中,需要声明全局变量AMap和AMapUI:
在这里插入图片描述


版权声明:本文为weixin_43877486原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。