vue異步加載高德地圖

幾種加載js的方式

  1. 同步加載
  2. 異步加載
  3. 延遲加載

同步加載

用的最多的一種方式,又稱阻塞模式,會阻止瀏覽器的後續處理,中止後續的解析,只有噹噹前加載完成,才能進行下一步操做。因此默認同步執行纔是安全的。但這樣若是js中有輸出document內容、修改dom、重定向等行爲,就會形成頁面堵塞。因此通常建議把<script>標籤放在<body>結尾處,這樣儘量減小頁面阻塞。javascript

<script src="http://webapi.amap.com/maps?v=1.4.7&key=您申請的key值"></script>

異步加載

異步加載又叫非阻塞加載,瀏覽器在下載執行js的同時,還會繼續進行後續頁面的處理。主要有三種方式。vue

  • 動態建立script標籤
let script = document.createElement("script");
    script.type = "text/javascript";
    script.src = "//webapi.amap.com/maps?v=1.4.6&key="+key+"&callback=init";
    script.onerror = reject;
    document.head.appendChild(script);

新的<script>元素加載 file1.js 源文件。此文件當元素添加到頁面以後馬上開始下載。此技術的重點在於:不管在何處啓動下載,文件的下載和運行都不會阻塞其餘頁面處理過程,充分的利用了瀏覽器的多進程,但要注意,瀏覽器不保證文件加載的順序java

  • defer屬性

defer 屬性規定是否對腳本執行進行延遲,直到頁面加載爲止。web

  • async屬性

async的定義和用法(是HTML5的屬性),async 屬性規定一旦腳本可用,則會異步執行。
若是沒有async和defer屬性,那麼瀏覽器會當即執行當前的js腳本,阻塞後面的腳本;若是有async屬性,加載和渲染後續文檔元素的過程將和當前js的加載與執行並行進行(異步);若是有defer屬性,那麼加載後續文檔元素的過程將和 script.js 的加載並行進行(異步),可是 script.js 的執行要在全部元素(DOM)解析完成以後,DOMContentLoaded 事件觸發以前完成。api

引入高德地圖的方式

順序同步加載

這種方式下,地圖初始化的代碼要放在 JS API 的腳本標籤以後:數組

<script src="http://webapi.amap.com/maps?v=1.4.7&key=您申請的key值"></script>
<script type="text/javascript">
    var map = new AMap.Map('container', {
       center:[117.000923,36.675807],
       zoom:11
    });
</script>

這種方式有缺點很明顯,1:會致使加載頁面變得很慢;2:單頁應用的頁面,若是頁面中雖然用不到地圖,可是也會加載這個js文件,這是沒有必要的。promise

異步加載

異步加載指的是爲 JS API 指定加載的回調函數,在 JS API 的主體資源加載完畢以後,將自動調用該回調函數。回調函數應該聲明在 JS API 入口文件引用以前,異步加載能夠減小對其餘腳本執行的阻塞,HTTPS 下咱們也建議使用異步方式:瀏覽器

<script type="text/javascript">
    window.init = function(){
        var map = new AMap.Map('container', {
           center:[117.000923,36.675807],
           zoom:11
        });
    }
</script>
<script src="http://webapi.amap.com/maps?v=1.4.6&key=您申請的key值&callback=init"></script>

或者安全

window.onLoad  = function(){
    var map = new AMap.Map('container');
}
var url = 'http://webapi.amap.com/maps?v=1.4.6&key=您申請的key值&callback=onLoad';
var jsapi = doc.createElement('script');
jsapi.charset = 'utf-8';
jsapi.src = url;
document.head.appendChild(jsapi);

vue項目中引入高德地圖

如何在vue的組件化開發中引入高德地圖呢?我寫了一個loadMap.js文件app

export function MP(key) {
  return new Promise(function (resolve, reject) {
    window.init = function () {
      resolve(AMap)
    };
    let script = document.createElement("script");
    script.type = "text/javascript";
    script.src = "//webapi.amap.com/maps?v=1.4.6&key="+key+"&callback=init";
    script.onerror = reject;
    document.head.appendChild(script);
  })
}

而後在用到高德地圖的vue的組件中

import {MP} from '../../../utils/loadMap';
MP('d275691902d1744cad9a7ddc1fc20657').then(function (AMap) {
  that.errNetwork = false;
  initAMapUI(); //這裏調用initAMapUI初始化
  that.initMap(AMap);
}).catch(err=>{
  that.errNetwork = true;
})

小坑

在這兒我不只用到了高德地圖,還用到的地圖的UI庫。在高德地圖JavaScript API以後引入UI組件庫的入口文件:
同步方式

<!--引入高德地圖JSAPI -->
<script src="//webapi.amap.com/maps?v=1.3&key=您申請的key值"></script>

<!--引入UI組件庫(1.0版本) -->
<script src="//webapi.amap.com/ui/1.0/main.js"></script>

異步方式

<!--異步加載 高德地圖JSAPI ,注意 callback 參數-->
<script src="//webapi.amap.com/maps?v=1.3&key=您申請的key值&callback=my_init"></script>

<!--引入UI組件庫異步版本main-async.js(1.0版本) -->
<script src="//webapi.amap.com/ui/1.0/main-async.js"></script>

<script type="text/javascript">
//JSAPI回調入口
function my_init() {
       initAMapUI(); //這裏調用initAMapUI初始化
       //其餘邏輯
}
</script>

關鍵是UI庫依賴於地圖js文件,在這裏,咱們能夠js加載完的回調onload函數和promise.all()函數來實現。loadMap.js文件以下:

export function MP(key) {
  const p1 =  new Promise(function (resolve, reject) {
    window.init = function () {
      console.log('script1-------onload');
      resolve(AMap)
    };
    let script = document.createElement("script");
    script.type = "text/javascript";
    script.src = "//webapi.amap.com/maps?v=1.4.6&key="+key+"&callback=init";
    script.onerror = reject;
    document.head.appendChild(script);
  });
  const p2 = new Promise(function (resolve,reject) {
    let script2 = document.createElement("script");
    script2.type = "text/javascript";
    script2.src = "//webapi.amap.com/ui/1.0/main-async.js";
    script2.onerror = reject;
    script2.onload = function(su){
      console.log('script2-------onload',su);
      resolve('success')
    };
    document.head.appendChild(script2);
  });
  return Promise.all([p1,p2])
    .then(function (result) {
      console.log('result----------->',result);
      return result[0]
    }).catch(e=>{
      console.log(e);})
};

promise.all中的then的成功回調返回rusult是一個數組,分別表明p1和p2的結果,這裏只返回p1的結果(map對象)就能夠了。

相關文章
相關標籤/搜索