背景:在使用Vue做項目的時候,需要使用百度地圖,使用了 vue-baidu-map插件
實現的功能包括:地圖的縮放,動態比例尺,動態設置地圖中心點,根據經緯度在地圖上進行標點,點擊標記點打開信息窗口展示詳情
開工之前需要在項目中安裝 ` vue-baidu-map` 的依賴
npm install vue-baidu-map --save
1.引入方式
- 可以在 app.js 中全局引入(如果不是每個組件中都使用此組件不推薦全局引入)
import BaiduMap from 'vue-baidu-map' Vue.use(BaiduMap, { /* 需要你在百度開放平台上注冊,並申請ak */ /* 項目上線時,記得要使用公司信息注冊的ak */ ak:'YOUR_APP_KEY' })
- 局部引入,引入方式與全局引入不同,需要在node_modules/vue-baidu-map/components 里面找到需要的組件
注意:局部引入要在 `<baidu-map ak=''></baidu-map>`中聲明ak屬性
//項目中引入使用百度地圖的組件 import BaiduMap from 'vue-baidu-map/components/map/Map.vue' // 百度地圖組件 import BmScale from 'vue-baidu-map/components/controls/Scale' // 比例尺組件 import BmNavigation from 'vue-baidu-map/components/controls/Navigation' // 縮放組件 import BmMarker from 'vue-baidu-map/components/overlays/Marker' // 標記點的組件 import BmLabel from 'vue-baidu-map/components/overlays/Label' // 標簽組件,展示在標記點中的數字 import BmInfoWindow from 'vue-baidu-map/components/overlays/InfoWindow' // 信息窗體 // 組件的注冊 export default { components: { BaiduMap, BmScale, BmNavigation, BmMarker, BmInfoWindow, BmLabel }, }
2.在組件中的使用,代碼如下

<baidu-map class="bm-view" :center="center" // 動態設置中心點,center數據格式 => center:{lng:116.404,lat:39.915},可根據定位到不同的城市,動態改變值 :zoom="zoom" // 地圖顯示比例尺的大小,必須定義,有1~19個級別 @ready="handler" // 地圖API加載完畢后執行的代碼 :scroll-wheel-zoom="true" // 鼠標滾輪控制縮放 :mapClick="false" // 禁止點擊景點彈出信息窗體,自定義的除外 ak="YOUR_APP_KEY" // 你申請的ak值 > <!-- 比例尺控件,注冊此組件才會在地圖上顯示比例尺 --> <bm-scale anchor="BMAP_ANCHOR_TOP_RIGHT"></bm-scale> <!-- 縮放控件,注冊此組件才會顯示拖放進度 --> <bm-navigation anchor="BMAP_ANCHOR_TOP_RIGHT"></bm-navigation> <div v-for="(marker, index) in markers" :key="marker.id"> <!-- 標記點組件 --> <bm-marker :position="{ lng: marker.lng, lat: marker.lat }" :title="marker.servestationname" @click="infoWindowOpen(marker)" > <!-- 信息窗體組件 --> <bm-info-window :title="marker.servestationname" :position="{ lng: marker.lng, lat: marker.lat }" :show="marker.showFlag" @close="infoWindowClose(marker)" > <p> {{ marker.servestationaddress }} </p> <p>服務車型:{{ marker.brandandcartype }}</p> <p>聯系人:{{ marker.handler }}</p> <p>聯系熱線:{{ marker.phone }}</p> </bm-info-window> <!-- 標簽組件 --> <bm-label :content="index + 1 + ''" :labelStyle="{ color: '#fff', fontSize: '12px', background: 'rgba(0, 0, 0, 0)', borderColor: 'rgba(0, 0, 0, 0)', }" :offset="{ width: index >= 9 ? 0 : 4, height: 2 }" /> </bm-marker> </div> </baidu-map> export default { data() { return { center: { lng: null, lat: null }, zoom: 13, // 地圖標記點數據 markers: [ { lng: 116.405, lat: 39.901, showFlag: false, //flag放在每一條數據里 }, { lng: 116.404, lat: 39.9, showFlag: false, }, ] } }, methods: { // 地圖初始化完成回調 handler({ BMap, map }) { this.center.lng = 116.404 this.center.lat = 39.915 }, // 關閉標記詳情 infoWindowClose(marker) { marker.showFlag = false }, // 打開標記詳情 infoWindowOpen(marker) { marker.showFlag = !marker.showFlag }, } }
3.總結使用過程中遇見的問題
這幾個問題是來自組件文檔的溫馨提示,已親測
BaiduMap
組件容器本身是一個空的塊級元素,如果容器不定義高度,百度地圖將渲染在一個高度為 0 不可見的容器內。- 沒有設置
center
和zoom
屬性的地圖組件是不進行地圖渲染的。當center
屬性為合法地名字符串時例外,因為百度地圖會根據地名自動調整zoom
的值。
- 由於百度地圖 JS API 只有 JSONP 一種加載方式,因此
BaiduMap
組件及其所有子組件的渲染只能是異步的。因此,請使用在組件的ready
事件來執行地圖 API 加載完畢后才能執行的代碼,不要試圖在 vue 自身的生命周期中調用BMap
類,更不要在這些時機修改 model 層。
現在總結下本次遇見的問題
- 第一次在項目中使用,所以組件內引入組件有點暈,在經過一番百度之后,發現需要去依賴中找路徑,和你需要的各個組件;每個功能都是一個組件!!!
- 縮放組件問題,注冊完成后,鼠標滾輪不能進行縮放,問題是要在 `<baidu-map>` 標簽上配置 `:scroll-wheel-zoom="true"`
- 比例尺,縮放組件的 anchor屬性是配置元素在地圖上顯示的位置,參數詳見文檔
- 關於給你經緯度信息,如何在地圖上標記出來的問題,這里需要使用 marker 組件,因為不是一個標記點,需要渲染很多標記點,所以會出現很多問題
① 在bm-marker中使用v-for循環,但是bm-info-window只會創建一個
方案:在 marker 組件的外面套一層 div,使用 v-for 在上面進行渲染
② 創建的出來的標記點個數不固定,怎么按序號展示呢?
方案:這里需要使用 baidu-map 提供的 Label 組件,在這里需要給組件提供內容,樣式,展示的偏移位置,用到的屬性為:content,labelStyle,offset
③ 創建的出來的標記點,點擊怎么會顯示當前城市的詳情呢?
方案:這里需用 bm-info-window 組件,組件的標簽內寫需要的內容,該組件的 title 屬性為信息窗的標題,可動態寫入;組件的 show 屬性控制顯示/隱藏,position屬性控制窗體位置
④在切換多個城市坐標時,標記點 根據上面 代碼中的 markers 數據動態渲染,再點擊標記點時,信息窗不能彈出
問題排查:經過調試,發現點擊事件可以觸發,可以拿到最新的 markers 數據,但是事件傳參的對象確是第一次的數據,疑惑?這應該是dom沒有更新,看到外層的 v-for 渲染時,為了偷懶,key屬性的值用的是index,切換坐標時,重新渲染的標記點的key值相同,所以 虛擬dom 的惰性觸發,這里改成 id就解決啦!
⑤ 在自定義信息窗樣式時,要寫在全局樣式中
- 下面奉上比例尺級別對應的數據
經過一路的踩坑,終於完成啦!