vue3中动态引入BMap

只有几个页面用到地图,不想首屏加载地图,因为用的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
  }
}

上一篇:Gradle Kotlin DSL 多模块项目案例


下一篇:SQL 优化极简法则,还有谁不会?