1. 相关文档和工具
百度地图插件地址(插件文档在github项目代码里,可下载下来运行项目阅读)
百度地图 javascript API(插件的文档有些并未解释完全,需要结合官方API文档阅读)
密钥申请(必须要申请开发者密钥才可以使用百度地图)
坐标拾取器(用来获取地图上点的经纬度)
2.引入
效果图
步骤:
- 注册组件
- 初始化地图
- 添加缩放控件
- 添加地图类型控件
- 添加点
- 添加线
- 添加信息窗体
- 添加外部浮层
2.1 安装注册组件
安装组件
$ npm install vue-baidu-map --save
注册组件
<template>
// ak 是在百度地图开发者平台申请的密钥 详见 http://lbsyun.baidu.com/apiconsole/key */
<baidu-map class="bm-view" ak="YOUR_APP_KEY">
</baidu-map>
</template>
<script>
import BaiduMap from 'vue-baidu-map/components/map/Map.vue'
export default {
components: {
BaiduMap
}
}
</script>
<style>
.bm-view {
width: 100%;
height: 300px;
}
</style>
可全局注册,也可局部注册,因为我只有一个页面用到地图,所以采用局部注册
2.2 初始化地图
<template>
<baidu-map id="baidumap" class="map" ak="KbGbuk~~~BWmEjf"
:center="map.center"
:zoom="map.zoom"
:scroll-wheel-zoom="map.scroll">
</baidu-map>
</template>
<script>
import BaiduMap from 'vue-baidu-map/components/map/Map.vue'//用什么引入什么就好,路径在下载的github项目中可以看到
export default {
name: "Map",
components: {
BaiduMap
},
data() {
return {
map: {
center: {lng: 112.127671, lat: 32.015287},//'襄阳市',地图的中心点坐标
zoom: 15,//1-18,数值越大离地面越近,地图实际面积越小
scroll: true //支持滚动鼠标缩放
}
}
}
}
</script>
<style lang="stylus" scoped>
.map
width auto
height 750px //宽高一定要设置
margin 0 20px 20px 20px
</style>
2.3 添加缩放控件
<template>
<baidu-map id="baidumap" class="map" ak="KbGbuk~~~BWmEjf"
:center="map.center"
:zoom="map.zoom"
:scroll-wheel-zoom="map.scroll">
<!-- 缩放控件,所有地图的组件都要写在 baidu-map组件内-->
<bm-navigation anchor="BMAP_ANCHOR_TOP_LEFT"></bm-navigation>
</baidu-map>
</template>
<script>
import BaiduMap from 'vue-baidu-map/components/map/Map.vue'
import BmNavigation from 'vue-baidu-map/components/controls/Navigation.vue'//引入缩放控件
export default {
name: "Map",
components: {
BaiduMap, BmNavigation//注册组件
},
...
}
</script>
关于anchor属性,插件文档中的说明是
但文档中并未说明ControlAnchor类型是什么,此时要用到百度地图 javascript API,找到官方文档解释:
后面的操作就同理啦,插件文档中没有详细说明的东西都可以去官方API文档中查找,毕竟插件也是在官方js的基础上写的嘛(我真厉害哈哈O(∩_∩)O)
2.4 添加地图类型控件
<template>
<baidu-map id="baidumap" class="map" ak="KbGbuk~~~BWmEjf"
:center="map.center"
:zoom="map.zoom"
:scroll-wheel-zoom="map.scroll">
<!-- 地图类型控件 -->
<bm-map-type :map-types="['BMAP_NORMAL_MAP', 'BMAP_HYBRID_MAP']" anchor="BMAP_ANCHOR_TOP_RIGHT"></bm-map-type>
</baidu-map>
</template>
<script>
import BaiduMap from 'vue-baidu-map/components/map/Map.vue'
import BmMapType from 'vue-baidu-map/components/controls/MapType.vue'//类型组件
export default {
name: "Map",
components: {
BaiduMap, BmMapType//注册
},
...
}
</script>
同理,找到官方文档百度地图 javascript API,设置地图类型:
2.5 添加点
<template>
<baidu-map id="baidumap" class="map" ak="KbGbuk~~~BWmEjf"
:center="map.center"
:zoom="map.zoom"
:scroll-wheel-zoom="map.scroll">
<!-- 各设备在地图上显示 -->
<!-- 循环输出点,key值一定要设置全局唯一的,不要用数组下标;如果只显示一个点就去掉循环-->
<!-- 可以自定义图标 -->
<!-- 设置点击事件,点击后打开信息窗体 -->
<bm-marker v-for="item of deviceInfo.devicelist" :key="item._id" :position="{lng: item.lng, lat: item.lat}"
:icon="{url: 'https://gitee.com/hyflu4/imgs/raw/master/baidu-map-icons/ren.png', size: {width: 48, height: 32}}"
@click="infoWindowOpen(item,1)"
>
</bm-marker>
</baidu-map>
</template>
<script>
import BaiduMap from 'vue-baidu-map/components/map/Map.vue'//用什么引入什么就好,路径在下载的github项目中可以看到
import BmMarker from 'vue-baidu-map/components/overlays/Marker.vue'
export default {
name: "Map",
components: {
BaiduMap, BmMarker
},
props: ['deviceInfo'],
...
}
</script>
这里是循环输出多个点,直接在marker组件上使用v-for,不需要加div来循环(来自一个小白走过的坑...)
2.6 添加线
<template>
<baidu-map id="baidumap" class="map" ak="KbGbuk~~~BWmEjf"
:center="map.center"
:zoom="map.zoom"
:scroll-wheel-zoom="map.scroll">
<!-- 输出所有的点 -->
<bm-marker v-for="item of towers" :key="item._id" :position="{lng: item.lng, lat: item.lat}"
:icon="{url: 'https://gitee.com/hyflu4/imgs/raw/master/baidu-map-icons/meishi.png', size: {width: 32, height: 32}}"
@click="infoWindowOpen(item,2)"
>
</bm-marker>
<!-- 一条线,只需要path中给出组成线的点坐标数组 -->
<!-- 多条线,即一个二维数组,需要用到v-for -->
<bm-polyline v-for="(item,key) of towerLines" :key="key" :path="item" stroke-color="red"
:stroke-opacity="1" :stroke-weight="3">
</bm-polyline>
</baidu-map>
</template>
<script>
import BaiduMap from 'vue-baidu-map/components/map/Map.vue'
import BmMarker from 'vue-baidu-map/components/overlays/Marker.vue'
import BmPolyline from 'vue-baidu-map/components/overlays/Polyline.vue'
export default {
name: "Map",
components: {
BaiduMap, BmMarker,BmPolyline
},
props: ['deviceInfo', 'towerlineInfo'],
data() {
return {
map: {
center: {lng: 112.127671, lat: 32.015287},//'襄阳市',地图的中心点坐标
zoom: 15,//1-18,数值越大离地面越近,地图实际面积越小
scroll: true //支持滚动鼠标缩放
},
towerLines: [],
towers: []
}
}
}
</script>
- 线是由多个点组成的,因此只要给出点的数组就能画出线啦~
- 线和点是分开的,当需要既显示点,又显示点连成的线时,还是需要分成点和线
- 这里给出线的数据结构以供参考:
towerLines:[
[{lng:'12.12',lat:'13.13'},{lng:'13.13',lat:'14.14'},{lng:'14.14',lat:'15.15}],//第一条线
[{lng:'12.12',lat:'13.13'},{lng:'13.13',lat:'14.14'},{lng:'14.14',lat:'15.15}],//第二条线
]
2.7 添加信息窗体
<template>
<baidu-map id="baidumap" class="map" ak="KbGbuknrQ3M9Ms9uwb260MpQAdBWmEjf"
:center="map.center"
:zoom="map.zoom"
:scroll-wheel-zoom="map.scroll"
>
<bm-info-window :show="infoWindow.show" :position="infoWindow.position"
class="info-window"
@open="infoWindowOpen"
@close="infoWindowClose">
<!--此处是自定义窗体内容,你也可以用{{}}的方式直接输出内容-->
<div class="info-Window-name">{{infoWindow.title}}</div>
<div v-for="(item,key) of infoWindow.contents" :key="key">{{item}}</div>
</bm-info-window>
</baidu-map>
</template>
<script>
import BaiduMap from 'vue-baidu-map/components/map/Map.vue'
import BmInfoWindow from 'vue-baidu-map/components/overlays/InfoWindow.vue'
export default {
name: "Map",
components: {
BaiduMap,BmInfoWindow
},
props: ['deviceInfo', 'towerlineInfo'],
data() {
return {
map: {
center: {lng: 112.127671, lat: 32.015287},//'襄阳市',
zoom: 15,//1-18
scroll: true
},
infoWindow: {
show: false,
position: {},
title: '',
contents: []
},
}
},
methods: {
clickDevice(data) {
this.infoWindow.position = {lng: data.lng, lat: data.lat}
this.infoWindow.title = data.devicename
this.infoWindow.contents = []
this.infoWindow.contents.push(
'等级:' + data.elecstrength,
'状态:' + (data.isarmclose ? '已抵达' : '已离开'),
'经度:' + data.lng,
'纬度:' + data.lat
)
},
clickTower(data) {
this.infoWindow.position = {lng: data.lng, lat: data.lat}
this.infoWindow.title = data.towername
this.infoWindow.contents = []
this.infoWindow.contents.push(
'线路名称:' + data.linename,
'线路等级:' + data.vlevel,
'经度:' + data.lng,
'纬度:' + data.lat
)
},
infoWindowClose() {
this.infoWindow.show = false
},
//type不同,初始化数据的方法不同
infoWindowOpen(data,type) {
this.infoWindow.show = true
switch (type) {
case 1:
this.clickDevice(data)
break
case 2:
this.clickTower(data)
break
}
},
},
}
</script>
<style lang="stylus" scoped>
.map
width auto
height 750px
margin 0 20px 20px 20px
position relative
.info-window
font-size 12px
.info-Window-name
font-weight bold
text-align center
</style>
- tips: 此处有两种类型的点,但我使用了同一个窗体显示数据,因为在使用两个窗体显示数据时,两个窗体在切换时必须要先关掉上个窗体才能打开下个窗体,体验不太好
2.8 添加外部浮层
<baidu-map id="baidumap" class="map" ak="KbGbuk~~~BWmEjf"
:center="map.center"
:zoom="map.zoom"
:scroll-wheel-zoom="map.scroll">
<div class="sum-message">
当前人数<span class="sum-message-num" style="color:#66b1ff;">{{deviceInfo.totalnum}}</span>个,
在线人数<span class="sum-message-num" style="color:#00a84b;" >{{deviceInfo.onlinenum}}</span>个,
离线人数<span class="sum-message-num" style="color:#cdcdcd;">{{deviceInfo.offlinenum}}</span>个,
矿工人数<span class="sum-message-num" style="color:#d81e06;">{{deviceInfo.warmnum}}</span>个
</div>
</baidu-map>
<style lang="stylus" scoped>
.map
width auto
height 750px //宽高一定要设置
margin 0 20px 20px 20px
position relative
.sum-message
position absolute
left 50%
top 0
transform translateX(-50%);
z-index 1
background-color rgba(255, 255, 255, 0.8)
border-radius 8px
padding 0 10px
width auto
height 40px
line-height 40px
.sum-message-num
font-size 18px
padding 0 3px
font-weight bold
</style>
让浮层可以居中显示的关键代码:
.map
position relative
.sum-message
position absolute
left 50%
top 0
transform translateX(-50%);
3 心得
虽然自己已经用过第三方插件,比如element-ui和swiper,但是都是按照别人的文章指引,总是糊里糊涂的在用,仿佛插件是个很神秘的东西。
这次,通过百度地图插件的引入过程,我终于揭开了插件这个神秘的面纱,我看到了源码、文档,虽然没有看太懂,但是也让我不再“畏惧”插件,至少让我懂得:vue的插件也就是用vue写的一些组件罢了!