将自定义vue组件加载在Mapbox或Maplibre的marker和popup上

ops/2025/3/7 1:53:03/

1. 使用场景

在开发WebGIS应用时,我们常需要将自定义UI组件与地图元素结合。本文介绍如何将Vue组件集成到Mapbox/Maplibre的Marker标记点和Popup弹窗中,实现动态交互式的地图功能。

2. 为什么需要特殊处理?

在常规开发中我们大多的处理是

javascript">const tipsEle = document.createElement("div")tipsEle.setAttribute("class", "tips")tipsEle.style.color = "#e73f32"tipsEle.style.fontSize = "12px"tipsEle.style.fontWeight = "400"tipsEle.innerHTML = "删除"const tipsOption = {element: tipsEle,anchor: "left",offset: [-45, 30],}new maplibregl.Marker(tipsOption).setLngLat(coords).addTo(map)

这样的写法显而易见维护难,调试难,ui在复杂一点复杂程度也跟着上去了,如果换成组件形式的话,所有问题迎刃而解了。

3. 使用createVNode实现

javascript">/*** @description: 创建地图Marker 和 Popup 组件, 渲染自定义组件* @author: jihai* @createTime: 2025/03/05 15:05:01*/
import {createVNode, render} from "vue";
import * as maplibregl from 'maplibre-gl';class CreateVNode{declare map:anydeclare coordinates:anydeclare markerComponentId: stringdeclare marker:anydeclare markerElement: anydeclare popupComponentId: stringdeclare popup:anydeclare popupElement: anyconstructor(option: {map: any,coordinates: any}) {const {map, coordinates} = optionthis.map = mapthis.coordinates = coordinatesthis.markerComponentId = `markerComponentId-${performance.now().toString()}`this.marker = nullthis.markerElement = nullthis.popupComponentId = `popupComponentId-${performance.now().toString()}`this.popup = nullthis.popupElement = null}createMarker(options: {component: {component: any, // 自定义vue组件props: any      // 自定义组件props},config?: {offset: number[],anchor: string}}){const { component, config } = optionsconst app = createVNode(component?.component, {data: component?.props})this.markerElement = document.createElement("div")this.markerElement.setAttribute("id", this.markerComponentId)this.marker = new maplibregl.Marker({element: this.markerElement,anchor: config?.anchor ?? 'bottom',offset: config?.offset ?? [0, 0]}).setLngLat(this.coordinates).addTo(this.map)render(app, this.markerElement)}createPopup(options: {component: {component: any, // 自定义vue组件props: any      // 自定义vue组件props},config?: {offset: number[],anchor: string,closeButton: boolean}}){const { component, config } = optionsconst app = createVNode(component?.component, {data: component?.props})this.popupElement = document.createElement("div")this.popupElement.setAttribute("id", this.popupComponentId)this.popup = new maplibregl.Popup({className: 'custom-popup', closeButton: config?.closeButton ?? true, anchor: config?.anchor ?? 'bottom'}).setMaxWidth('none').setOffset(config?.offset ?? [0, 0]) // 这里设置偏移量.setLngLat(this.coordinates).setDOMContent(this.popupElement).addTo(this.map)render(app, this.popupElement)}removeMarker(){if(this.marker){this.marker.remove()}if(this.markerElement){this.markerElement.remove()}}removePopup(){if(this.popup){this.popup.remove()}if(this.popupElement){this.popupElement.remove()}}remove(){this.removeMarker()this.removePopup()}
}export default CreateVNode

4. 使用方法

javascript">  // 简单使用 具体使用根据业务场景合理清除图层let marker = new CreateVNode({map: map,coordinates: coordinates})marker.createMarker({component: {component: markerComp,props: markerProps},config: {offset: [0, 120],anchor: 'bottom'}})//  图层清除marker.removeMarker()marker = null

5. 效果展示

红色框里为element组件渲染结果
在这里插入图片描述


http://www.ppmy.cn/ops/163753.html

相关文章

Java面试--Linux

面试题:Linux查看cpu占用率高的进程(阿里面试题) 面试题:查看占用某端口的进程(阿里面试题) 面试题:查看某进程监听的端口(阿里面试题) 面试题:查看系统负载(今日头条面试题) 面试题:查看进程中线程的状态(蘑菇街面试题…

Threejs实现加载loading动画

大家好!我是 [数擎AI],一位热爱探索新技术的前端开发者,在这里分享前端和Web3D、AI技术的干货与实战经验。如果你对技术有热情,欢迎关注我的文章,我们一起成长、进步! 开发领域:前端开发 | AI 应…

如何在Python用Plot画出一个简单的机器人模型

如何在Python中使用 Plot 画出一个简单的模型 在下面的程序中,首先要知道机器人的DH参数,然后计算出每一个关节的位置,最后利用 plot 函数画出关节之间的连杆就可以了,最后利用 animation 库来实现一个动画效果。 import matplo…

transformer架构解析{掩码,(自)注意力机制,多头(自)注意力机制}(含代码)-3

目录 前言 掩码张量 什么是掩码张量 掩码张量的作用 生成掩码张量实现 注意力机制 学习目标 注意力计算规则 注意力和自注意力 注意力机制 注意力机制计算规则的代码实现 多头注意力机制 学习目标 什么是多头注意力机制 多头注意力计算机制的作用 多头注意力机…

使用DeepSeek实现自动化编程:类的自动生成

目录 简述 1. 通过注释生成C类 1.1 模糊生成 1.2 把控细节,让结果更精准 1.3 让DeepSeek自动生成代码 2. 验证DeepSeek自动生成的代码 2.1 安装SQLite命令行工具 2.2 验证DeepSeek代码 3. 测试代码下载 简述 在现代软件开发中,自动化编程工具如…

防火墙虚拟系统实验

拓扑图 需求一 安全策略要求: 1、只存在一个公网IP地址,公司内网所有部门都需要借用同一个接口访问外网 2、财务部禁止访问Internet,研发部门只有部分员工可以访问Internet,行政部门全部可以访问互联网 3、为三个部门的虚拟系统分…

FPGA——4位全加器及3-8译码器的实现

文章目录 一、全加器1、Verilog实现四位全加器2、下载测试 二、3-8译码器1、Verilog实现3-8译码器2、7段数码管显示3-8译码器 三、总结四、参考资料 一、全加器 全加器的定义: 全加器英语名称为full-adder,是用门电路实现两个二进制数相加并求出和的组合…

android11使用gpio口控制led状态灯

目录 一、简介 二、解决方法 A、底层驱动 B、上层调用 C、验证 一、简介 1、需求:这里是用2个gpio口来控制LED灯,开机时默认亮蓝灯,按开机键,休眠亮红灯,唤醒亮蓝灯。 原理图: 这里由于主板上电阻R63…