vue中引入百度地图:一个小白的vue插件探索之路

1. 相关文档和工具

百度地图插件地址(插件文档在github项目代码里,可下载下来运行项目阅读)
百度地图 javascript API(插件的文档有些并未解释完全,需要结合官方API文档阅读)
密钥申请(必须要申请开发者密钥才可以使用百度地图)
坐标拾取器(用来获取地图上点的经纬度)

2.引入

效果图

步骤:

  1. 注册组件
  2. 初始化地图
  3. 添加缩放控件
  4. 添加地图类型控件
  5. 添加点
  6. 添加线
  7. 添加信息窗体
  8. 添加外部浮层

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写的一些组件罢了!

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。