**Vue3 接入高德地图 API:初始化、定位、Marker 与常用封装**
·
在 Vue3 项目里接高德地图,建议直接做成“脚本加载 + 公共方法封装”的方式,后续多个页面复用更省事。常见需求基本就是:地图初始化、Marker 标记、定位、地图选点、逆地理编码、地址解析、路线规划。
先封装地图脚本加载,避免重复引入,也避免 `AMap is not defined`:
// src/utils/loadAMap.js
let amapPromise = null
export function loadAMap() {
// 如果已加载则直接返回
if (window.AMap) return Promise.resolve(window.AMap)
// 避免重复加载
if (amapPromise) return amapPromise
amapPromise = new Promise((resolve, reject) => {
const script = document.createElement('script')
script.src = 'https://webapi.amap.com/maps?v=2.0&key=***&plugin=AMap.Geolocation,AMap.Geocoder,AMap.Driving'
script.async = true
script.onload = () => resolve(window.AMap)
script.onerror = () => reject(new Error('高德地图加载失败'))
document.head.appendChild(script)
})
return amapPromise
}
页面里最小初始化写法:
<template>
<div id="map-container"></div>
</template>
<script setup>
import { onMounted, onBeforeUnmount } from 'vue'
import { loadAMap } from '@/utils/loadAMap'
let map = null
let AMapRef = null
async function initMap() {
const AMap = await loadAMap()
AMapRef = AMap
map = new AMap.Map('map-container', {
zoom: 12,
center: [116.397428, 39.90923],
resizeEnable: true
})
}
onMounted(initMap)
onBeforeUnmount(() => {
if (map) {
map.destroy()
map = null
}
})
</script>
<style scoped>
#map-container {
width: 100%;
height: 500px;
}
</style>
常用功能里,Marker 和信息窗体最常见:
function addMarker() {
const marker = new AMapRef.Marker({
position: [116.397428, 39.90923],
title: '天安门',
map
})
const infoWindow = new AMapRef.InfoWindow({
content: '<div>天安门</div>',
offset: new AMapRef.Pixel(0, -30)
})
marker.on('click', () => {
infoWindow.open(map, marker.getPosition())
})
}
定位和逆地理编码一般一起用:
function getCurrentPosition() {
map.plugin('AMap.Geolocation', () => {
const geolocation = new AMapRef.Geolocation({
enableHighAccuracy: true,
timeout: 10000
})
geolocation.getCurrentPosition((status, result) => {
if (status === 'complete') {
const { lng, lat } = result.position
map.setCenter([lng, lat])
new AMapRef.Marker({
position: [lng, lat],
map
})
const geocoder = new AMapRef.Geocoder()
geocoder.getAddress([lng, lat], (s, r) => {
if (s === 'complete' && r.info === 'OK') {
console.log(r.regeocode.formattedAddress)
}
})
}
})
})
}
地图选点也很实用,适合门店选址、地址回填:
let currentMarker = null
function bindMapClick() {
map.on('click', e => {
const { lng, lat } = e.lnglat
if (currentMarker) {
map.remove(currentMarker)
}
currentMarker = new AMapRef.Marker({
position: [lng, lat],
map
})
map.setCenter([lng, lat])
})
}
如果要做地址转坐标、路线规划,也建议直接封装:
function geocodeAddress(address) {
const geocoder = new AMapRef.Geocoder()
geocoder.getLocation(address, (status, result) => {
if (status === 'complete' && result.info === 'OK') {
console.log(result.geocodes)
}
})
}
function planRoute(start, end) {
map.plugin('AMap.Driving', () => {
const driving = new AMapRef.Driving({ map })
driving.search(start, end)
})
}
最后记住几个高频坑就够了:
- 地图不显示,先查容器高度
- `AMap is not defined`,基本都是脚本没加载完
- 经纬度顺序固定是 `[lng, lat]`
- 定位失败先查浏览器权限
- 页面切换后异常,记得销毁地图实例
这套写法适合大多数 Vue3 项目。
更多推荐
所有评论(0)