详解vue-amap引入高德JS API的原理

目录
  • vue-amap使用
  • vue-amap入口文件
  • initAMapApiLoader方法
  • AMapAPILoader类
  • _getScriptSrc方法
  • loadUIAMap方法
  • 总结

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="https://webapi.amap.com/ui/1.1/main-async.js"></script>

总结

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

到此这篇关于详解vue-amap引入高德JS API的原理的文章就介绍到这了,更多相关vue-amap引入高德JS API内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Vue 引入AMap高德地图的实现代码

    本文代码仅针对 Vue CLI 3.x 生成的项目有效,但是在第二步配置的时候,可以直接配置 webpack.externals,所以本引入思路是通用的,并不局限于该项目 资源 AMap 准备-入门教程 引入 AMap 在 public/index.html 文件 </body> 前引入 <script type="text/javascript" src="https://webapi.amap.com/maps?v=1.4.14&key=您申请的

  • vue 使用高德地图vue-amap组件过程解析

    这篇文章主要介绍了vue 使用高德地图vue-amap组件过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 首先 npm install -S vue-amap 然后在 main.js import VueAMap from 'vue-amap'; //注意不要和 AMap原始名称覆盖 Vue.use(VueAMap); // 初始化vue-amap VueAMap.initAMapApiLoader({ // 高德的key key: '

  • 最全vue的vue-amap使用高德地图插件画多边形范围的示例代码

    一.在vue-cli的框架下的main.js(或者main.ts)中引入高德插件,代码如下: import Vue from 'vue' import VueAMap from 'vue-amap' import ElementUI from 'element-ui' import App from './App.vue' import router from './router' import store from './store' import './registerServiceWork

  • 详解vue-amap引入高德JS API的原理

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

  • 详解Vue项目引入CreateJS的方法(亲测可用)

    1 前 言 1.1 CreateJS介绍 CreateJS是基于HTML5开发的一套模块化的库和工具. 基于这些库,可以非常快捷地开发出基于HTML5的游戏.动画和交互应用. A suite of modular libraries and tools which work together or independently to enable rich interactive content on open web technologies via HTML5. 包含4类工具库 EaselJS

  • 详解Vue 全局引入bass.scss 处理方案

    为解决在Vue组件中全局引入 scss 变量及 mixins ,装载了一个名为 "sass-resources-loader" 解析器. 安装 $ > cnpm i -D sass-resources-loader 配置 配置的话是在 vue 的 loader 解析器中配置,即在 vue-cli 脚手架方式构建出来的文件中是以 build/utils.js,在该文件中定义了 cssLoaders() 方法,该方法定义了诸如 css.less的解析方式,具体如下. // build

  • 详解vue中引入stylus及报错解决方法

    前提条件是已经有了vue项目,如果没有,请先建立,具体方法看这里https://cn.vuejs.org/v2/guide/installation.html 安装stylus 好了,建立好项目后我们来安装stylus npm install stylus stylus-loader --save-dev 这样就安装上了stylus. 接下来就可以使用了,使用方式分两种.一种是在.vue文件的style块中使用,一种是引用.styl文件的形式 在.vue文件的style块中使用 这个很简单,只要

  • 详解Vue中Axios封装API接口的思路及方法

    一.axios的封装 在vue项目中,和后台交互获取数据这块,我们通常使用的是axios库,它是基于promise的http库,可运行在浏览器端和node.js中.他有很多优秀的特性,例如拦截请求和响应.取消请求.转换json.客户端防御XSRF等. 在一个项目中我们如果要使用很多接口的话,总不能在每个页面都写满了.get()或者.post()吧?所以我们就要自己手动封装一个全局的Axios网络模块,这样的话就既方便也会使代码量不那么冗余. 安装 > npm install axios //这个

  • 详解 vue.js用法和特性

    前  言 最近用Vue.js做了一个数据查询平台,还做了一个拼图游戏,突然深深的感到了vue的强大. Vue.js是一套构建用户界面(user interface)的渐进式框架.与其他重量级框架不同的是,Vue 从根本上采用最小成本.渐进增量(incrementally adoptable)的设计.Vue 的核心库只专注于视图层,并且很容易与其他第三方库或现有项目集成.另一方面,当与单文件组件和 Vue 生态系统支持的库结合使用时,Vue 也完全能够为复杂的单页应用程序提供有力驱动. Vue.j

  • 详解Vue.js中.native修饰符

    修饰符(Modifiers)是以半角句号 . 指明的特殊后缀,用于指出一个指令应该以特殊方式绑定.这篇文章给大家介绍Vue.js中.native修饰符,感兴趣的朋友一起看看吧. .native修饰符 官方对.native修饰符的解释为: 有时候,你可能想在某个组件的根元素上监听一个原生事件.可以使用 v-on 的修饰符 .native .例如: <my-component v-on:click.native="doTheThing"></my-component>

  • 详解Vue.js 响应接口

    Vue 可以添加数据动态响应接口. 例如以下实例,我们通过使用 $watch 属性来实现数据的监听,$watch 必须添加在 Vue 实例之外才能实现正确的响应. 实例中通过点击按钮计数器会加 1.setTimeout 设置 10 秒后计算器的值加上 20 . <div id = "app"> <p style = "font-size:25px;">计数器: {{ counter }}</p> <button @click

  • 详解Vue.js 可拖放文本框组件的使用

    可拖放文本框允许用户通过拖动备选项至文本框来确定输入,其实也可以说是 combobox 的一种变形. 与 combobox 相比,这种组件能让用户更加直观的看到所有备选项,并且可以是多个输入共用一组备选项. 类似的组件也曾用在 3D Windrose App,Graph Maker App 等多个 app 里. 注册组件 注册可拖放文本框组件(其实就是将封装好的这部分代码 Ctrl+C and Ctrl+V). <script type="text/x-template" id=

  • 详解Vue文档中几个易忽视部分的剖析

    针对Vue文档中部分大家可能不会去研读的内容,我做了个小总结,作为有经验者的快餐,不是特别适合初学者,可能有不妥之处,希望大家多提建议. 节省代码量的mixin mixin概念:组件级可复用逻辑,包括数据变量/生命周期钩子/公共方法,从而在混入的组件中可以直接使用,不用重复写冗余逻辑(类似继承) 使用方法: 在某一公共文件夹pub下创建mixin文件夹,其下创建mixinTest.js const mixinTest = { created() { console.log(`components

随机推荐