插件窝 干货文章 Vue 3.0项目如何优雅地集成百度地图及其扩展库?

Vue 3.0项目如何优雅地集成百度地图及其扩展库?

map script const 地图 338    来源:    2025-03-25

Vue 3.0集成百度地图及其扩展库的优雅方案

方案概述

在Vue 3.0项目中集成百度地图及其扩展库,推荐采用以下优雅的实现方式:

1. 使用官方JavaScript API

安装依赖

npm install vue-baidu-map-3x --save

全局注册

// main.js
import { createApp } from 'vue'
import App from './App.vue'
import BaiduMap from 'vue-baidu-map-3x'

const app = createApp(App)

app.use(BaiduMap, {
  // 百度地图AK
  ak: 'YOUR_BAIDU_MAP_AK'
})

app.mount('#app')

组件中使用

<template>
  <baidu-map class="map" :center="center" :zoom="zoom" @ready="handler">
    <bm-view class="map"></bm-view>
    <bm-marker :position="markerPoint" :dragging="true" @click="infoWindowOpen"></bm-marker>
    <bm-info-window :position="infoWindow.position" :show="infoWindow.show" @close="infoWindowClose">
      {{ infoWindow.contents }}
    </bm-info-window>
  </baidu-map>
</template>

<script>
import { ref } from 'vue'

export default {
  setup() {
    const center = ref({lng: 116.404, lat: 39.915})
    const zoom = ref(15)
    const markerPoint = ref({lng: 116.404, lat: 39.915})
    const infoWindow = ref({
      show: false,
      position: {lng: 116.404, lat: 39.915},
      contents: '这里是信息窗口内容'
    })

    const handler = ({BMap, map}) => {
      console.log('地图初始化完成', BMap, map)
    }

    const infoWindowOpen = () => {
      infoWindow.value.show = true
    }

    const infoWindowClose = () => {
      infoWindow.value.show = false
    }

    return {
      center,
      zoom,
      markerPoint,
      infoWindow,
      handler,
      infoWindowOpen,
      infoWindowClose
    }
  }
}
</script>

<style scoped>
.map {
  width: 100%;
  height: 400px;
}
</style>

2. 动态加载百度地图API(推荐)

对于更灵活的控制,可以采用动态加载方式:

// utils/loadBMap.js
export default function loadBMap(ak) {
  return new Promise((resolve, reject) => {
    if (typeof window.BMap !== 'undefined') {
      resolve(window.BMap)
      return
    }

    window.onBMapCallback = function() {
      resolve(window.BMap)
    }

    const script = document.createElement('script')
    script.type = 'text/javascript'
    script.src = `https://api.map.baidu.com/api?v=3.0&ak=${ak}&callback=onBMapCallback`
    script.onerror = reject
    document.head.appendChild(script)
  })
}

在组件中使用:

<script>
import { onMounted, ref } from 'vue'
import loadBMap from '@/utils/loadBMap'

export default {
  setup() {
    const map = ref(null)

    onMounted(async () => {
      try {
        const BMap = await loadBMap('YOUR_BAIDU_MAP_AK')
        map.value = new BMap.Map('map-container')
        // 初始化地图中心点和缩放级别
        map.value.centerAndZoom(new BMap.Point(116.404, 39.915), 15)
        // 添加控件
        map.value.addControl(new BMap.NavigationControl())
        map.value.addControl(new BMap.ScaleControl())
      } catch (error) {
        console.error('百度地图加载失败', error)
      }
    })

    return { map }
  }
}
</script>

3. 集成扩展库(如热力图、轨迹等)

// 加载扩展库
function loadBMapGL(ak) {
  return new Promise((resolve, reject) => {
    if (typeof window.BMapGL !== 'undefined') {
      resolve(window.BMapGL)
      return
    }

    const script = document.createElement('script')
    script.type = 'text/javascript'
    script.src = `https://api.map.baidu.com/api?v=3.0&ak=${ak}&type=webgl`
    script.onerror = reject
    document.head.appendChild(script)

    script.onload = function() {
      resolve(window.BMapGL)
    }
  })
}

// 热力图示例
async function initHeatmap() {
  const BMapGL = await loadBMapGL('YOUR_BAIDU_MAP_AK')
  const map = new BMapGL.Map('map-container')

  // 创建热力图图层
  const heatmapOverlay = new BMapGL.HeatmapOverlay({
    radius: 20,
    visible: true
  })
  map.addOverlay(heatmapOverlay)

  // 设置热力图数据
  const points = [
    {lng: 116.418261, lat: 39.921984, count: 50},
    {lng: 116.423332, lat: 39.916532, count: 51},
    // 更多数据点...
  ]

  heatmapOverlay.setDataSet({
    data: points,
    max: 100
  })
}

最佳实践建议

  1. 按需加载:只在需要地图的页面加载百度地图API,减少首屏加载时间
  2. 组件封装:将常用地图功能封装为可复用的Vue组件
  3. 错误处理:做好加载失败的处理和降级方案
  4. 性能优化:大数据量展示时考虑使用WebGL版本或分页加载
  5. 类型支持:为TypeScript项目添加类型定义
// types/baidu-map.d.ts
declare namespace BMap {
  class Map {
    constructor(container: string | HTMLElement)
    centerAndZoom(center: Point, zoom: number): void
    addControl(control: NavigationControl | ScaleControl | OverviewMapControl): void
    // 其他方法...
  }

  class Point {
    constructor(lng: number, lat: number)
  }

  // 其他类定义...
}

declare const BMAP_NORMAL_MAP: string
declare const BMAP_HYBRID_MAP: string
// 其他常量...

通过以上方案,可以在Vue 3.0项目中优雅地集成百度地图及其扩展库,同时保持良好的代码结构和性能表现。