只有几个页面用到地图,不想首屏加载地图,因为用的ts,目前没有方案可以完全跑下来,所以手动补全
1. 在utiles文件夹下新建loadMap.js,注意,如果你的网站是HTTPS类型,加载的资源也需要是HTTPS类型
// loadMap.ts
/**
* @description 加载百度地图相关资源js
*/
export default function loadBMap(): Promise<void> {
return new Promise<void>((resolve, reject) => {
//聚合API依赖基础库,因此先加载基础库再加载聚合API
///MarkerClusterer_min.js依赖TextIconOverlay.js。因此先加载TextIconOverlay.js
const textIconOverlayUrl = 'https://api.map.baidu.com/library/TextIconOverlay/1.2/src/TextIconOverlay.js'
const markerClusterer_min = 'https://api.map.baidu.com/library/MarkerClusterer/1.2/src/MarkerClusterer_min.js'
try {
resolve(
loadBaiduMapJs().then(() => {
resolve(
loadJs(textIconOverlayUrl).then(() => {
resolve(loadJs(markerClusterer_min))
})
)
})
)
} catch (err) {
reject(err)
}
})
}
/**
* @description 加载百度地图基础组件js
*/
export function loadBaiduMapJs(): Promise<void> {
const AK = '你的AK'
const BMap_URL = 'https://api.map.baidu.com/api?v=2.0&ak=' + AK + '&callback=onBMapCallback'
return new Promise((resolve, reject) => {
try {
// 如果已加载直接返回
const BMap = window.BMap
if (typeof BMap !== 'undefined') {
resolve(BMap)
return true
}
window.onBMapCallback = function () {
resolve(BMap)
}
const scriptNode = document.createElement('script')
scriptNode.setAttribute('type', 'text/javascript')
scriptNode.setAttribute('src', BMap_URL)
document.head.appendChild(scriptNode)
} catch (err) {
const scriptNode = document.createElement('script')
scriptNode.setAttribute('type', 'text/javascript')
scriptNode.onerror = reject
}
})
}
/**
* @description 加载第三方组件js公共方法
* @param {string} url
*/
export function loadJs(url: string): Promise<void> {
return new Promise<void>((resolve, reject) => {
try {
const scriptNode = document.createElement('script')
scriptNode.setAttribute('type', 'text/javascript')
scriptNode.setAttribute('src', url)
document.head.appendChild(scriptNode)
scriptNode.onload = () => {
resolve()
}
} catch (err) {
const scriptNode = document.createElement('script')
scriptNode.setAttribute('type', 'text/javascript')
scriptNode.onerror = reject
}
})
}
2.
// store 下 geoLocation.ts
import { defineStore } from 'pinia'
import loadBMap from '@/utils/loadBMap'
interface ICoordinateInfo {
lng: string
lat: string
}
interface IAddressInfo {
city: string
}
export const useGeoLocationStore = defineStore('geographicalLocation', {
state: () => {
return {
provinceAndCityInfo: {
cityName: '',
provinceName: '',
},
coordinateInfo: {
lng: '',
lat: '',
},
}
},
getters: {
getProvinceAndCityInfo(): ILocationInfo {
return this.provinceAndCityInfo
},
getCoordinateInfo(): ICoordinateInfo {
return this.coordinateInfo
},
},
actions: {
async setLocationInfo() {
navigator.geolocation.getCurrentPosition(async () => {
// 借助navigator访问用户是否给权限获取地址, pc和mobile都可用,如给了权限就继续执行,不给权限就会自动return
await loadBMap()
const BMap = window.BMap
// 根据Geolocation会更准确些,LocalCity是通过IP在百度地图数据库查询位置,不准确的概率比较大
const geolocation = new BMap.Geolocation()
await geolocation.getCurrentPosition(async (result: { point: ICoordinateInfo; address: IAddressInfo }) => {
if (geolocation.getStatus() === 0) {
this.coordinateInfo = Object.assign(result.point)
this.provinceAndCityInfo = Object.assign(result.address)
}
})
})
},
},
})
3 .global.d.ts中加入
// global.d.ts
declare global {
interface Window {
BMap: T
}
}