首页>>前端>>Vue->vue

vue

时间:2023-12-01 本站 点击:0

vue-amap是对高德地图JS API进行封装的、适用于vue项目的地图组件库。在笔者开发的很多项目中都有用到,相比直接使用高德地图JS API 来说,vue-amap更加好用,符合vue开发者的编程习惯。本文通过vue-amap源码分析了vue-amap引入高德JS API的原理。

vue-amap使用

在使用vue-amap时,main.js文件往往有这样一段代码:

import VueAMap from 'vue-amap'Vue.use(VueAMap)VueAMap.initAMapApiLoader({  key: '82732XXXXXa5eXXXXb3face28c25',//你的高德key  plugin: [    'AMap.Autocomplete',    'AMap.PlaceSearch',    'AMap.Scale',    'AMap.OverView',    'AMap.ToolBar',    'AMap.MapType',    'AMap.PolyEditor',    'AMap.CircleEditor'  ],  // 默认高德 sdk 版本为 1.4.4  v: '1.4.14'})

这段代码的关键就是initAMapApiLoader方法。

vue-amap入口文件

看vue-amap源码,index.js 文件有如下代码(部分代码):

// 初始化接口import {initAMapApiLoader} from './services/injected-amap-api-instance';export {  AMapManager,  initAMapApiLoader,  createCustomComponent};

可见initAMapApiLoader方法是被vue-amap直接向使用者暴露的,我们研究其具体实现。

initAMapApiLoader方法

接着我们到对应目录查看initAMapApiLoader的定义:

let lazyAMapApiLoaderInstance = null;import AMapAPILoader from './lazy-amap-api-loader';import Vue from 'vue';export const initAMapApiLoader = (config) => {  if (Vue.prototype.$isServer) return;  // if (lazyAMapApiLoaderInstance) throw new Error('You has already initial your lazyAMapApiLoaderInstance, just import it');  if (lazyAMapApiLoaderInstance) return;  if (!lazyAMapApiLoaderInstance) lazyAMapApiLoaderInstance = new AMapAPILoader(config);  lazyAMapApiLoaderInstance.load();};

initAMapApiLoader中使用到了lazy-amap-api-loader中定义的AMapAPILoader类,new了一个实例,并且调用了load()方法。

AMapAPILoader类

下面我们就看一下AMapAPILoader类的定义:

看长长的代码先折叠,了解大概

下面就看load()方法:

load() {  // 如果window上挂载了AMap,那么直接调用loadUIAMap()  if (this._window.AMap && this._window.AMap.Map) {    return this.loadUIAMap();  }  if (this._scriptLoadingPromise) return this._scriptLoadingPromise;  // 新建一个script标签  const script = this._document.createElement('script');  script.type = 'text/javascript';  // 异步执行  script.async = true;  script.defer = true;  script.src = this._getScriptSrc();  const UIPromise = this._config.uiVersion ? this.loadUIAMap() : null;  this._scriptLoadingPromise = new Promise((resolve, reject) => {    this._window['amapInitComponent'] = () => {      while (this._queueEvents.length) {        this._queueEvents.pop().apply();      }      if (UIPromise) {        UIPromise.then(() => {          // initAMapUI 这里调用initAMapUI初始化          window.initAMapUI();          setTimeout(resolve);        });      } else {        return resolve();      }    };    script.onerror = error => reject(error);  });  // script标签插入到head中  this._document.head.appendChild(script);  return this._scriptLoadingPromise;}

可以看到这段代码做了两件事情:(1)增加引入高德的script标签 ,script标签的src是通过 _getScriptSrc生成的 (2)引入AMapUI 组件库 ,通过调用loadUIAMap实现

下面分别来看这两个方法:

_getScriptSrc方法

_getScriptSrc() {  // amap plugin prefix reg  // 插件前缀  const amap_prefix_reg = /^AMap./;  const config = this._config;  const paramKeys = ['v', 'key', 'plugin', 'callback'];  // check 'AMap.' prefix  if (config.plugin && config.plugin.length > 0) {    // push default types    config.plugin.push('Autocomplete', 'PlaceSearch', 'PolyEditor', 'CircleEditor');    const plugins = [];    // fixed plugin name compatibility.    // 拼接插件    config.plugin.forEach(item => {      const prefixName = (amap_prefix_reg.test(item)) ? item : 'AMap.' + item;      const pureName = prefixName.replace(amap_prefix_reg, '');      plugins.push(prefixName, pureName);    });    config.plugin = plugins;  }  const params = Object.keys(config)  .filter(k => ~paramKeys.indexOf(k))  .filter(k => config[k] != null)  .filter(k => {    return !Array.isArray(config[k]) ||      (Array.isArray(config[k]) && config[k].length > 0);  })  .map(k => {    let v = config[k];    if (Array.isArray(v)) return { key: k, value: v.join(',')};    return {key: k, value: v};  })  .map(entry => `${entry.key}=${entry.value}`)  .join('&');  return `${this._config.protocol}://${this._config.hostAndPath}?${params}`;}

这段代码的作用就是最终要生成如下的字符串:

"https://webapi.amap.com/maps?v=1.4.15&key=你的key&plugin=AMap.Scale&plugin=AMap.ToolBar&plugin=AMap.PolyEditor&plugin=AMap.Autocomplete,AMap.PlaceSearch&plugin=AMap.Geocoder"

从而可以在index.html中加入这样的script, 这样就把高度地图的js-api引入了

<script type="text/javascript" src="https://webapi.amap.com/maps?v=1.4.15&key=你的key&plugin=AMap.Scale&plugin=AMap.ToolBar&plugin=AMap.PolyEditor&plugin=AMap.Autocomplete,AMap.PlaceSearch&plugin=AMap.Geocoder"></script>

loadUIAMap方法

再来看loadUIAMap

loadUIAMap() {  if (!this._config.uiVersion || window.AMapUI) return Promise.resolve();  return new Promise((resolve, reject) => {    const UIScript = document.createElement('script');    const [versionMain, versionSub, versionDetail] = this._config.uiVersion.split('.');    if (versionMain === undefined || versionSub === undefined) {      console.error('amap ui version is not correct, please check! version: ', this._config.uiVersion);      return;    }    let src = `${this._config.protocol}://webapi.amap.com/ui/${versionMain}.${versionSub}/main-async.js`;    if (versionDetail) src += `?v=${versionMain}.${versionSub}.${versionDetail}`;    UIScript.src = src;    UIScript.type = 'text/javascript';    UIScript.async = true;    this._document.head.appendChild(UIScript);    UIScript.onload = () => {      setTimeout(resolve, 0);    };    UIScript.onerror = () => reject();  });}

这段代码的作用是要在index.html文件中插入加载 AMapUI 的script标签,如下所示:

<script async src="//webapi.amap.com/ui/1.1/main-async.js"></script>

总结

一句话总结vue-amap引入高德地图API的原理:vue-map之所以能够使用高德地图的JS API 以及 AMapUI 是因为通过生成引入JS API 和 AMapUI的script标签,并将标签插入到项目的html文件。

原文:https://juejin.cn/post/7103733273573982245


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:/Vue/6550.html