在index.html引入百度地图开发包如下:
……
接着eslint报错BMap未定义,但是地图加载进来了能正常使用,只需配置eslint让其识别BMap这个全局变量,方法同cdn引入第三方包时的配置:
1、修改webpack.base.conf.js
externals: {
'vue': 'Vue',
'vue-router': 'VueRouter',
……
'BMap': 'window.BMap'
},
2、修改配置文件.eslintrc.js
globals: {
'Vue': true,
'VueRouter': true,
……
'BMap': true
}
至此可以正常创建一个地图div容器,初始化使用百度地图了,注意容器的高度宽度设置,否则地图可能显示不出来。
代码设置如下:
initMap () {
this.map = new BMap.Map('mapContent') // 在百度地图容器中创建一个地图
let point = new BMap.Point(113.331084, 23.112223) // 坐标点为广州塔
this.map.centerAndZoom(point, 12) // 设定地图的中心点和坐标并将地图显示在地图容器中
// 给地图上添加一个标注-广州塔
let cIcon = new BMap.Icon('/static/img/map/marker_' + state + '.png', new BMap.Size(20, 30))
let label = new BMap.Label(slabel, {offset: new BMap.Size(20, -10)})
let marker = new BMap.Marker(point, {icon: cIcon})
// 给label设置样式 display: 'none' label先不显示光标移动到其上才显示
label.setStyle({border: 'none', background: '#409eff', color: 'white', padding: '2px 4px'})
marker.setLabel(label)
/* eslint-disable */
// marker.setAnimation(BMAP_ANIMATION_BOUNCE) // 添加mark的动画效果 - 弹跳
/* eslint-enable */
this.map.addOverlay(marker) // 将标注添加到地图中
},
问题现象如下:
很明显广州塔标注位置不对,真正的广州塔也不在正中心展示。
放大地图后,标注位置跳到了正确位置。
说明坐标没有问题。如下存在两个问题:
1、centerAndZoom设置的中心点不在中心位置
2、初始化标注点位置存在偏离
一个个问题解决
很多人说是创建地图的时候div隐藏了?高宽为0?
但是我是在mounted后才创建的地图,照道理说这时候dom都已经挂载完了,再说了高宽为0初始化地图难道不报错吗?
陷入沉思……
于是我打印出dom的宽度发现
mounted () {
this.initMap() // 创建和初始化地图
/* setTimeout(() => {
this.initMap() // 创建和初始化地图
}, 2000) */
},
initMap () {
this.map = new BMap.Map('mapContent') // 在百度地图容器中创建一个地图
console.log(document.getElementById('mapContent').offsetHeight, 111)
let point = new BMap.Point(113.331084,23.112223)
……
},
当未使用setTimeout延迟地图初始化时,打印出的宽度为1872px;
在使用了setTimeout延迟地图初始化后,打印出的宽度为1644px;
相差51px,虽说用setTimeout延迟加载即可解决问题,但是延迟时间不可控啊,根本原因也没查出来。
继续陷入沉思……
因为界面的布局是,左边菜单,点击相应菜单进入嵌入百度地图的子路由。于是修改左侧菜单的宽度……
// el-aside的宽度设置从220px改为420px后
当未使用setTimeout延迟地图初始化时,打印出的宽度为1872px;
在使用了setTimeout延迟地图初始化后,打印出的宽度为1444px;
也就是说,初始加载地图,其容器获取的高宽是几乎整个屏幕的高宽……
接着发现,未使用setTimeout延迟地图初始化时:
在el-aside选择菜单切换路由的时候,宽度打印1444px,中心点正常;
刷新当前地图所在路由页面时,宽度打印1872px,中心点偏离;
同时,在三个mounted里打印el-aside的宽度顺序发现
// 最外层路由
mounted () {
console.log(document.getElementById('testaaa').offsetWidth, 'main')
setTimeout(() => {
console.log(document.getElementById('testaaa').offsetWidth, 'main')
}, 1000)
},
// el-aside左侧菜单中
mounted () {
console.log(document.getElementById('testaaa').offsetWidth, 'el-aside')
},
// 地图所在路由页面下
mounted () {
console.log(document.getElementById('testaaa').offsetWidth, 'baidu-map')
},
控制台打印结果如下:
0 “el-aside”
0 “baidu-map”
0 “main”
220 “main”
也就是说,地图加载的时候,菜单还没有获取到其宽度,大概是因为父级路由等所有加载完成后,才给菜单宽度赋值。
导致地图加载先于el-aside的菜单的宽度设置,所以地图容器div没有减去左边菜单的div宽度。
至于解决办法锁定在延迟地图的加载,于是在地图子路由下尝试:
mounted () {
console.log(document.getElementById('mapContent').offsetWidth, 'baidu-map')
setTimeout(() => {
console.log(document.getElementById('mapContent').offsetWidth, 'baidu-map')
this.initMap() // 创建和初始化地图
}, 0)
},
查看控制台打印如下
调用setTimeout时,把函数参数,放到事件队列中。等主程序运行完,再调用。
导致setTimeout哪怕是0s后的函数都成功在父路由加载完成后才执行,成功解决了中心点偏离的问题。
第一个问题解决完后发现
!!!所有初始化标注点的位置都正确了