谷歌地图与右键菜单
写在前面
首先非常感谢这位组件的作者,苦恼了一段时间的问题终于解决了。 这里给出这个组件的地址vue3-context-menu (imengyu.top)
需求
大致描述一下需求是怎么样的吧,就是要在谷歌地图上编辑多边形,然后呢,要给每一个多边形添加一个右键点击事件,右键点击会弹出一个菜单,苦于谷歌地图没有提供这方面的示例和文档,最贴合的一个示例还是使用类继承来实现的,当我看到this的时候马上就切掉了,因为项目使用的是vue3。而且网上很多相关的文章教程都挺老了的。看到文章发表日期大多都是15年左右的了,压根都不带看的。
效果
懒人移步
内容不多,要是嫌麻烦我这里也给出这个视图的.vue文件源码 template
<template>
<div class="map-container" v-show="true">
<div id="map"></div>
</div>
<svg viewBox="0 0 80 20" xmlns="http://www.w3.org/2000/svg">
<!-- Your icon -->
<symbol id="icon-edit" viewBox="0 0 1024 1024">
<path
d="M904 318.72l-207.552-207.552 45.248-45.248 207.552 207.552-45.248 45.248z m-522.24 522.24l-231.232 46.272A19.2 19.2 0 0 1 128 864.64l46.272-231.232L641.216 166.4l207.616 207.552-467.072 467.072z m376.576-467.008l-117.12-117.12-408.064 408.128-29.248 146.368 146.304-29.312 408.128-408.064z"
fill="#000000" fill-opacity=".9" p-id="4276">
</path>
</symbol>
</svg>
<svg viewBox="0 0 80 20" xmlns="http://www.w3.org/2000/svg">
<!-- Your icon -->
<symbol id="icon-delete" viewBox="0 0 1024 1024">
<path
d="M640 64a64 64 0 0 1 64 64v85.333h226.133c4.694 0 8.534 3.84 8.534 8.534V268.8a8.533 8.533 0 0 1-8.534 8.533h-55.466V832a128 128 0 0 1-128 128H277.333a128 128 0 0 1-128-128V277.333H93.867a8.533 8.533 0 0 1-8.534-8.533v-46.933c0-4.694 3.84-8.534 8.534-8.534H320V128a64 64 0 0 1 64-64h256z m170.667 213.333H213.333V832a64 64 0 0 0 60.246 63.893l3.754 0.107h469.334a64 64 0 0 0 63.893-60.245l0.107-3.755V277.333z m-392.534 128c4.694 0 8.534 3.84 8.534 8.534v324.266a8.533 8.533 0 0 1-8.534 8.534H371.2a8.533 8.533 0 0 1-8.533-8.534V413.867c0-4.694 3.84-8.534 8.533-8.534h46.933z m234.667 0c4.693 0 8.533 3.84 8.533 8.534v324.266a8.533 8.533 0 0 1-8.533 8.534h-46.933a8.533 8.533 0 0 1-8.534-8.534V413.867c0-4.694 3.84-8.534 8.534-8.534H652.8zM640 128H384v85.333h256V128z"
fill="#000000" p-id="5443"></path>
</symbol>
</svg>
</template>
typescript
<script setup lang="ts">
import { ref, onBeforeMount } from 'vue'
import { zoneData, zoneType } from "@/test/map/testData";
import ContextMenu from '@imengyu/vue3-context-menu'
const map = ref<google.maps.Map | null>(null) // 地图实例
const polygonList = ref<google.maps.Polygon[]>([]) // 多边形列表
const drawingManager = ref<google.maps.drawing.DrawingManager | null>(null) // 绘制工具实例
const currentPolygon = ref<google.maps.Polygon | null>(null) // 当前多边形
async function initMap(): Promise<void> {
const { Map } = (await google.maps.importLibrary('maps')) as google.maps.MapsLibrary;
map.value = new Map(document.getElementById('map') as HTMLElement, {
center: { lat: 40.682227, lng: -74.144292 },
zoom: 14,
mapId: 'your map id', // 你的地图id
})
}
onBeforeMount(async () => {
await initMap()
zoneData.forEach(async (zone) => {
const polygon = new google.maps.Polygon({
paths: zone.paths,
...zoneType.default
})
/**这部分是右键菜单的核心代码 */
polygon.addListener('contextmenu', (e: google.maps.PolyMouseEvent) => {
const domEvent: PointerEvent = e.domEvent as PointerEvent
const x = domEvent.x
const y = domEvent.y
ContextMenu.showContextMenu({
x: x,
y: y,
customClass: 'my-menu-box',
items: [
{
label: "Edit",
svgIcon: "#icon-edit",
onClick: () => {
alert("You click a menu Edit");
}
},
{
label: "Delete",
svgIcon: "#icon-delete",
onClick: () => {
alert("You click a menu Delete");
}
},
]
});
})
polygon.setMap(map.value)
polygonList.value.push(polygon)
})
drawingManager.value = new google.maps.drawing.DrawingManager({
drawingMode: null,
drawingControl: false,
polygonOptions: {
strokeColor: '#42b903',
strokeOpacity: 0.8,
strokeWeight: 5,
fillColor: '#E7F8F1',
fillOpacity: 0.65,
editable: false
}
})
drawingManager.value.setMap(map.value)
// 添加绘制完成事件
google.maps.event.addListener(drawingManager.value, 'polygoncomplete', drawPolygonComplete)
})
const drawPolygonComplete = async (polygon: google.maps.Polygon) => {
drawingManager.value?.setDrawingMode(null)
polygonList.value.push(polygon)
currentPolygon.value = polygon
}
</script>
css
<style>
#map {
height: 100vh;
width: 100%;
}
.map-container {
display: flex;
width: 90%;
height: 90vh;
flex-direction: column;
margin: 0 auto;
}
.btn {
margin: 20px 0;
align-self: flex-start;
}
.my-menu-box {
border-radius: 16px !important;
background-color: #fff !important;
}
</style>