1.index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" href="/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title></title>
</head>
<body>
<div id="app"></div>
<script type="module" src="/src/main.ts"></script>
</body>
<script>
document.write(unescape("%3Cscript src='./config.local.js?_t=" + Math.random() + "' type='text/javascript'%3E%3C/script%3E"));
</script>
//添加AK
<script type="text/javascript" src="https://api.map.baidu.com/api?v=3.0&ak=自己的ak"></script>
</html>
2.在component文件夹下新建自定义子组件map-baidu.vue
<template>
<section class="map-baidu-box">
<div ref="mapRef"></div>
</section>
</template>
<script lang="ts" setup>
import darkJson from './json/dark-1.json';//地图背景
interface MarkIcon {
url: string,
size: [number, number],
}
interface MarkOption extends AnyObject {
x: number,
y: number,
icon: MarkIcon,
}
const emit = defineEmits(['map-ready', 'map-click', 'mark-click']);
const props = withDefaults(
defineProps<{
zoom?: number, // 缩放大小
point?: number[], // 展示的点位
markOptions?: MarkOption[], // 标记的点位
markTipTemplate?: Function, // 标记tip模板
}>(),
{
point: () => [120.27009107213996, 30.19237475223979],
}
);
const mapRef = ref();
const BMap = (window as any).BMap;
let mapInstance = null as any;
const markTooltip = document.createElement('div');
// 标记map
function setMapMark(markOption: MarkOption) {
// 创建图标
const myIcon = new BMap.Icon(
markOption.icon.url,
new BMap.Size(markOption.icon.size[0], markOption.icon.size[1])
);
// 设置mark坐标
const pt = new BMap.Point(markOption.x, markOption.y);
// 创建mark标注
const marker = new BMap.Marker(pt, { icon: myIcon });
// 将标注添加到地图
mapInstance.addOverlay(marker);
// 添加mark监听点击事件
marker.addEventListener('click', function (e: any) {
if (props.markTipTemplate) {
const tooltip = props.markTipTemplate(markOption);
markTooltip.remove();
markTooltip.innerHTML = tooltip;
e.target.Ec.appendChild(markTooltip);
e.domEvent.preventDefault();
e.domEvent.stopPropagation();
}
emit('mark-click', { e, markOption, mapInstance });
});
}
// 更新map标点
function updateMapMark(marks: MarkOption[]) {
marks.forEach(item => setMapMark(item));
}
// 更新map中心点位置和缩放大小
function updateMapPointAndZoom(point: number[], zoom: number = 14) {
mapInstance.centerAndZoom(new BMap.Point(point[0], point[1]), zoom);
}
// 重置中心点位置和缩放大小
function resetMapPointAndZoom() {
updateMapPointAndZoom(props.point, props.zoom);
}
onMounted(() => {
mapInstance = new BMap.Map(mapRef.value);
resetMapPointAndZoom();
mapInstance.enableScrollWheelZoom(true);
mapInstance.setMapStyleV2({ styleJson: darkJson });
mapInstance.addEventListener('click', function (e: any) {
markTooltip.remove();
emit('map-click', { e, mapInstance });
// markMap(map, [e.point.lng, e.point.lat], 1);
console.log('点击的经纬度:' + e.point.lng + ',' + e.point.lat);
});
updateMapMark(props.markOptions || []);
emit('map-ready', mapInstance);
});
watch(
() => props.markOptions,
async (value) => {
await nextTick();
updateMapMark(value || []);
},
{ deep: true }
);
defineExpose({ mapInstance, setMapMark, updateMapMark, updateMapPointAndZoom });
</script>
<style lang="scss">
.map-baidu-box {
height: 100%;
width: 100%;
> div {
width: 100%;
height: 100%;
}
.anchorBL a {
display: none;
}
}
</style>
3.父组件调用
<template>
<div class="map">
<map-baidu
:point="mapState.point"
:mark-options="mapState.markOptions"
:mark-tip-template="markTipTemplate"
/>
</div>
</template>
<script lang="ts" setup>
import mapMarkIcon from "@/assets/img/monitor/map-position.png";
//#region 地图
// 点位图标
const markIcon = { url: mapMarkIcon, size: [44 * 0.6, 53 * 0.6] };
// map配置项
const mapState = reactive<any>({
point: [120.27756497398268, 30.189003846530078],
markOptions: [
{ id: 1, x: 120.24307004239976, y: 30.209042695252734, icon: markIcon },
{ id: 2, x: 120.26103615259932, y: 30.207794267330275, icon: markIcon },
{ id: 3, x: 120.25543072621706, y: 30.193061609836626, icon: markIcon },
{ id: 4, x: 120.32743889589689, y: 30.17470509958105, icon: markIcon },
{ id: 5, x: 120.29538735530087, y: 30.209042695252734, icon: markIcon },
{ id: 6, x: 120.3350565266215, y: 30.173456231875097, icon: markIcon },
{ id: 7, x: 120.28144565378602, y: 30.223772936488828, icon: markIcon },
{ id: 8, x: 120.30674193694699, y: 30.191937841163863, icon: markIcon },
{ id: 9, x: 120.26003005042814, y: 30.167586339523147, icon: markIcon }
]
});
// tooltip模板
function markTipTemplate(markOption: any) {
const name = 'monitor-map-tooltip';
return `
<div class="${name}">
<div class="${name}__title">祝林红</div>
<div class="${name}__content">
<p>时间:2022-12-12 18:31:46</p>
<p>位置:广德小区8号楼1单元1101</p>
<p>报警内容:跌倒</p>
</div>
</div>
`;
}
//#endregion
</script>
<style lang="scss">
.map {
height: 493px;
margin-bottom: 19px;
}
</style>
版权声明:本文为weixin_45891332原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。