前端代码
<template><Dialog title="地图" v-model="show" width="700px" top="5vh" center><div id="container-wrapper"><baidu-mapclass="bm-view":center="center":zoom="18":scroll-wheel-zoom="true"@click="handleClick"@mousemove="syncPolyline"@rightclick="newPolyline"><bm-control v-show="mode == 0"><button @click.stop="toggle">{{ polyline.editing ? '停止绘制' : '开始绘制' }}</button><button @click.stop="clearPaths">{{ "清空绘制" }}</button></bm-control><!-- 标点模式 --><bm-marker v-if="mode == 1 && center" :position="center" :icon="markerIcon" /><bm-marker v-if="mode == 1 && clickPosition" :position="clickPosition" :icon="markerIcon" /><!-- 绘制模式 --><bm-polylinev-for="(path, index) in polyline.paths":key="index":path="path":stroke-color="'blue'"/></baidu-map></div><div v-if="mode === 1 && clickPosition" class="coordinates">当前选中坐标: 经度 {{ clickPosition.lng }},纬度 {{ clickPosition.lat }}</div><div v-if="mode == 0 && polyline.paths.length" class="coordinates">当前绘制路径: {{ JSON.stringify(polyline.paths) }}</div><template #footer><el-button @click="confirmAction" type="primary">确 定</el-button><el-button @click="cancelAction">取 消</el-button></template></Dialog>
</template><script setup>
import { ref ,toRef,nextTick} from "vue";const show = ref(false);
const center = ref({ lng: 119.4196557630222, lat: 32.39979425018851 }); // 默认中心点
const clickPosition = ref(null); // 存储点击位置的经纬度
const mode = ref(1); // 模式,1为标点模式,0为绘制模式
const polyline = ref({editing: false,paths: []
}); // 绘制模式的路径// 定义事件供父组件调用
const emit = defineEmits(["confirm"]);// 显示地图模态框
const showModal = (params = {}) => {console.log(polyline.value.paths);center.value = {lng: params.longitude ?? center.value.lng,lat: params.latitude ?? center.value.lat,};if(params.footpathList!=[]){polyline.value.paths = [params.footpathList._value];}else{polyline.value.paths = []; // 重置路径}clickPosition.value = null; // 重置选中位置mode.value = params.mode ?? 1; // 设置模式show.value = true;
};// 点击事件处理
const handleClick = (e) => {if (mode.value === 1) {clickPosition.value = e.point; // 标点模式} else if (mode.value === 0) {paintPolyline(e); // 绘制模式}
};const toggle = (name) => {if(polyline.value.editing){// 停止绘制时清理未完成的点cleanIncompletePath();}polyline.value.editing = !polyline.value.editing;
};
// 同步绘制的线
const syncPolyline = (e) => {if (!polyline.value.editing) {return}if (!polyline.value.paths.length) {return}const path = polyline.value.paths[polyline.value.paths.length - 1]if (!path.length) {return}if (path.length === 1) {polyline.value.paths[polyline.value.paths.length - 1].push(e.point)}polyline.value.paths[polyline.value.paths.length - 1][path.length - 1] = e.point;
};
// 清理未完成的路径(未闭合或单点的路径)
const cleanIncompletePath = () => {if (polyline.value.paths && polyline.value.paths.length > 0) {const currentPath = polyline.value.paths[polyline.value.paths.length - 1];// 如果当前路径有点,移除最后一个点if (currentPath && currentPath.length > 0) {currentPath.pop();}}
};
// 开始新绘制线段
const newPolyline = () => {if (!polyline.value.editing) {return}console.log(polyline.value.paths);if (!polyline.value.paths.length) {polyline.value.paths.push([])}const path = polyline.value.paths[polyline.value.paths.length - 1]path.pop()if (path.length) {polyline.value.paths.push([])}
};// 添加点到绘制路径
const paintPolyline = (e) => {if (!polyline.value.editing) {return}console.log(polyline.value.paths);!polyline.value.paths.length && polyline.value.paths.push([])polyline.value.paths[polyline.value.paths.length - 1].push(e.point)
};// 确认操作
const confirmAction = () => {if (mode.value === 1) {emit("confirm", clickPosition.value,mode.value); // 返回标点坐标} else if (mode.value === 0) {emit("confirm", polyline.value.paths[0],mode.value); // 返回路径数据}show.value = false;
};//清空绘制
const clearPaths = () => {console.log(polyline.value.paths);polyline.value.paths = []; // 清空所有路径polyline.value.editing = false; // 停止绘制状态
};
const cancelAction = () => {clickPosition.value = null; // 重置点击位置clearPaths();console.log(polyline.value.paths);show.value = false; // 关闭对话框};// 暴露给父组件
defineExpose({ showModal });
</script><style lang="scss" scoped>
#container-wrapper {position: relative;width: 100%;padding-bottom: 100%; /* 确保地图为正方形 */overflow: hidden;
}.bm-view {position: absolute;top: 0;left: 0;width: 100%;height: 100%;
}.coordinates {margin: 10px 0;font-size: 14px;color: #333;
}
</style>
后台管理效果如图