解决Vue引入百度地图JSSDK:BMap is undefined 问题

2018-01-12 程飞

百度地图官网文档介绍使用JSSDK时,仅提供了2种引入方式:

  • script引入
  • 异步加载

但vue项目中仅某一两个页面需要用到百度地图,所以不想在 index.html 中全局引用。

那在单个vue组件页面中如何引入呢?

刚开始时,是直接通过 DOM 操作方式插入script标签到当前document中,如下:

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);

结果是不行的。

然后考虑使用异步加载的方式,结合参考网上方案,单独创建 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("加载成功...")
	})
}
...

结果还是不行。

想了下原因,一、可能是vue中window.onload没有触发,二、百度地图JSSDK没有真正加载成功。

继续验证测试,发现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="/photo.php?url=http://api.map.baidu.com/getscript?v=3.0&ak=您的密钥&services=&t=20180102163224"></script>');
})();

从返回内容中看出,立即执行函数中再次插入了另外一个 标签,经检查发现这个 实际并没有插入成功。

既然如此,那就直接把脚本放到我们上面的代码中去加载,结果就真的成功了。

修改优化后的代码如下:

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这个问题有空再研究下。


用户评论
开源开发学习小组列表