Vue中引入百度地圖(實現縮放,標記,信息窗)


背景:在使用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
        },
    }
}
View Code

3.總結使用過程中遇見的問題

  這幾個問題是來自組件文檔的溫馨提示,已親測

  • BaiduMap 組件容器本身是一個空的塊級元素,如果容器不定義高度,百度地圖將渲染在一個高度為 0 不可見的容器內。
  • 沒有設置 centerzoom 屬性的地圖組件是不進行地圖渲染的。當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就解決啦!

  ⑤ 在自定義信息窗樣式時,要寫在全局樣式中

  • 下面奉上比例尺級別對應的數據

         

 

經過一路的踩坑,終於完成啦!

    

   傳送門:vue-baidu-map中文文檔

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM