最近在做一个北京地铁费用查询系统的Web,前端使用的是React。
后来查询到百度地图和高德地图都有实现好的地铁图API,可以直接使用(最后选择了百度,因为官方文档详细很多)。但是官方教程都是直接插入到一个原生HTML中。而我们都知道React使用JSX将元素渲染为DOM,主要问题就在于我在index.html中导入了百度地图的script,要怎么在React组件中使用。
以下解决方案以百度地图为例,适用于其他没有module的CDN方案,如果有更好的方法欢迎在评论区提出。
如果我们直接在index.html中,粘贴了script,然后在React组件中使用,会出现报错
'BmapSub' is not defined
说明React组件没有获取到对应的类和方法。
第一步,在你的index.html中,导入百度地铁的script。
<!-- index.html -->
<script type="text/javascript" src="https://api.map.baidu.com/api?type=subway&v=1.0&ak=您的密钥"></script>
第二步,用window这个全局变量来保存需要用到的类。
所有浏览器都支持 window 对象。它表示浏览器窗口。
所有 JavaScript 全局对象、函数以及变量均自动成为 window 对象的成员。
全局变量是 window 对象的属性,全局函数是 window 对象的方法。
所以我们在window中保存我们需要用到的类和方法。这里就保存BMapSubway
<!-- index.html -->
<script type="text/javascript" src="https://api.map.baidu.com/api?type=subway&v=1.0&ak=您的密钥"></script>
<script>
window.BMapSubway = BMapSubway; // 这里可以访问到BmapSubway这个类,所以直接设为全局类
</script>
第三步,愉快地在React组件中使用。
// Map.js
import React from 'react';
class Map extends React.Component {
createSubway (){
let BMapSub = window.BMapSub; // 关键,取全部变量为局部变量,然后使用
var subwayCityName = '北京';
var list = BMapSub.SubwayCitiesList;
var subwaycity = null;
for (var i = 0; i < list.length; i++) {
if (list[i].name === subwayCityName) {
subwaycity = list[i];
break;
}
}
var subway = new BMapSub.Subway('map', subwaycity.citycode);
subway.setZoom(1);
}
componentDidMount() {
this.createSubway();
}
render() {
return (
<div id="map">
</div>
);
}
}
export default Map;
多说一句,这里插入一下componentDidMount()
的使用。上面使用了componentDidMount()
,是因为我要把地铁图插入到我将要渲染的<div id="map"></div>
中,也就是我必须得等该div渲染完毕,我的代码才能获取到。(在原生HTML中,我们通过更改代码顺序就可以简单地实现)
而componentDidMount()
会在组件挂载后(插入 DOM 树中)立即调用。依赖于 DOM 节点的初始化应该放在这里。如需通过网络请求获取数据,此处是实例化请求的好地方。
所以,我把地图初始化放在了componentDidMount()
中,这样当页面渲染完毕,我就可以获取到<div id="map"></div>
并成功插入地图。