简介
在 Vue 项目中使用第三方地图插件是一个常见的需求,这里我们尝试使用 Vue 3 + TypeScript 来封装一个高德地图的 Hooks,方便在组件中快速使用高德地图。
Hooks定义
// 高德地图hooks
import AMapLoader from "@amap/amap-jsapi-loader";
// 这里引入自己在高德申请的地图相关key
import {
AMAP_MAP_KEY,
AMAP_MAP_SECURITY_KEY,
AMAP_MAP_SERVICE_HOST
} from "@/config/config";
// 这里我示例用的是vantUI组件库进行提示的
import "vant/es/toast/style";
import { showFailToast } from "vant";
import { onUnmounted, ref } from "vue";
/**
* 高德地图hooks
* @param domId 地图容器id
*/
export const useMap = ({ domId }: { domId?: string } = {}) => {
const AMap = ref();
const map = ref();
async function initMap() {
try {
(window as any)._AMapSecurityConfig = {
// 二者选其一,无serviceHost就优先使用securityJsCode
// 高德地图密匙
securityJsCode: AMAP_MAP_SECURITY_KEY
// 后台远程服务地址
// serviceHost: AMAP_MAP_SERVICE_HOST
};
AMap.value = await AMapLoader.load({
key: AMAP_MAP_KEY, // 申请好的Web端开发者Key,首次调用 load 时必填
version: "2.0", // 指定要加载的 JS API 的版本,缺省时默认为 1.4.15
plugins: [] // 需要使用的的插件列表,如比例尺'AMap.Scale'等
});
// 如果传入地图容器id,直接创建地图实例
map.value = domId && new AMap.value.Map(domId);
} catch (error) {
console.log(error);
// 提示错误
showFailToast((error as any)?.message || "Has Error");
}
}
// 销毁地图
function destroyMap() {
map.value && map.value.destroy();
}
onUnmounted(() => {
destroyMap();
});
return {
map,
AMap,
initMap
};
};
示例代码
<template>
<div class="page-container">
<!-- 位置详情-->
<div class="card">
<div class="base-info-title py-[4px]">位置详情</div>
<!-- 地图容器-->
<div id="container" class="w-[85vw] h-[30vh]"></div>
</div>
</div>
</template>
<script setup lang="ts">
import { onMounted, ref } from "vue";
import { useMap } from "@/hooks/useMap";
//#region <高德地图相关>
// 地图实例
const { AMap, initMap } = useMap();
function initMapPage(opts?: { lng: number; lat: number }) {
console.log("opts", opts);
console.log("AMap", AMap.value);
const map = new AMap.value.Map("container", {
zoom: 19, //初始地图级别
center: [opts?.lng, opts?.lat], //初始地图中心点
showIndoorMap: false //关闭室内地图
});
}
//#endregion
onMounted(async () => {
await initMap();
initMapPage({
lng: 116.397428,
lat: 39.90923
});
});
</script>
<style scoped lang="less">
.base-info-title {
//background-color: var(--van-primary-background-color);
font-weight: bold;
//color: white;
}
</style>