百度地圖官網文檔介紹使用JSSDK時,僅提供了2種引入方式:javascript
解決跨域問題,實例調用百度地圖
html
但vue項目中僅某一兩個頁面須要用到百度地圖,因此不想在 index.html
中全局引用。vue
那在單個vue組件頁面中如何引入呢?java
剛開始時,是直接經過 DOM 操做方式插入script標籤到當前document中,以下:segmentfault
let scriptNode = document.createElement("script"); scriptNode.setAttribute("type", "text/javascript"); scriptNode.setAttribute("src", "http://api.map.baidu.com/api?v=3.0&ak=您的密鑰"); document.body.appendChild(scriptNode);
結果是不行的。api
而後考慮使用異步加載的方式,結合參考網上方案,單首創建baidu-map.js
腳本:跨域
export default { init: function (){ const AK = "AK密鑰"; const apiVersion = "3.0"; const timestamp = new Date().getTime(); const BMap_URL = "http://api.map.baidu.com/api?v="+ apiVersion +"&ak="+ AK +"&services=&t=" + timestamp; return new Promise((resolve, reject) => { // 插入script腳本 let scriptNode = document.createElement("script"); scriptNode.setAttribute("type", "text/javascript"); scriptNode.setAttribute("src", BMap_URL); document.body.appendChild(scriptNode); // 等待頁面加載完畢回調 window.onload = function () { resolve(BMap) } }); } } // ------------------------- // vue引入調用 import BaiduMap from 'baidu-map'; ... mounted(){ BauduMap.init() .then((BMap) => { console.log(BMap) console.log("加載成功...") }) } ...
結果仍是不行。瀏覽器
想了下緣由,1、多是vue中window.onload沒有觸發,2、百度地圖JSSDK沒有真正加載成功。app
繼續驗證測試,發現window.onload可以正常觸發,那就是JSSDK沒有加載成功。異步
直接複製JSSDK URL瀏覽器中打開 http://api.map.baidu.com/api?v=3.0&ak=您的密鑰 ,關鍵點來了,打開後內容以下:
(function(){ window.BMap_loadScriptTime = (new Date).getTime(); document.write('<script type="text/javascript" src="http://api.map.baidu.com/getscript?v=3.0&ak=您的密鑰&services=&t=20180102163224"></script>'); })();
從返回內容中看出,當即執行函數中再次插入了另一個<scirpt>標籤,經檢查發現這個<scirpt>實際並無插入成功。
既然如此,那就直接把腳本放到咱們上面的代碼中去加載,結果就真的成功了。
修改優化後的代碼以下:
export default { init: function (){ console.log("初始化百度地圖腳本..."); const AK = "AK密鑰"; const apiVersion = "3.0"; const timestamp = new Date().getTime(); const BMap_URL = "http://api.map.baidu.com/getscript?v="+ apiVersion +"&ak="+ AK +"&services=&t=" + timestamp; return new Promise((resolve, reject) => { if(typeof BMap !== "undefined") { resolve(BMap); return true; } // 插入script腳本 let scriptNode = document.createElement("script"); scriptNode.setAttribute("type", "text/javascript"); scriptNode.setAttribute("src", BMap_URL); document.body.appendChild(scriptNode); // 等待頁面加載完畢回調 let timeout = 0; let interval = setInterval(() => { // 超時10秒加載失敗 if(timeout >= 20) { reject(); clearInterval(interval); console.error("百度地圖腳本初始化失敗..."); } // 加載成功 if(typeof BMap !== "undefined") { resolve(BMap); clearInterval(interval); console.log("百度地圖腳本初始化成功..."); } timeout += 1; }, 500); }); } }
問題到此就解決了,至於爲何用官網提供的地址沒有真正加載到JSSDK這個問題有空再研究下。
最新解決方案
export default { init: function (){ //console.log("初始化百度地圖腳本..."); const AK = "AK密鑰"; const BMap_URL = "https://api.map.baidu.com/api?v=2.0&ak="+ AK +"&s=1&callback=onBMapCallback"; return new Promise((resolve, reject) => { // 若是已加載直接返回 if(typeof BMap !== "undefined") { resolve(BMap); return true; } // 百度地圖異步加載回調處理 window.onBMapCallback = function () { console.log("百度地圖腳本初始化成功..."); resolve(BMap); }; // 插入script腳本 let scriptNode = document.createElement("script"); scriptNode.setAttribute("type", "text/javascript"); scriptNode.setAttribute("src", BMap_URL); document.body.appendChild(scriptNode); }); } }
優化以下:
http://api.map.baidu.com/api?v=2.0&ak=您的密鑰
callback
參數,異步加載必須使用此參數才能夠生效https
配置,經過 s=1
參數實現2.0
,經測試使用,發現3.0
版本在HTTPS環境下是有問題的,腳本內部某些請求固定使用HTTP,沒法正常使用。