在Vue 3.0项目中集成百度地图及其扩展库,推荐采用以下优雅的实现方式:
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>
对于更灵活的控制,可以采用动态加载方式:
// 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>
// 加载扩展库
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
})
}
// 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项目中优雅地集成百度地图及其扩展库,同时保持良好的代码结构和性能表现。