0๐
โ
<template>
<span :id="id" class="mapboxgl-ctrl mapboxgl-ctrl-group">
<button type="button">
<FitFeaturesIcon class="mapboxgl-ctrl-icon" aria-hidden="true" />
</button>
</span>
</template>
<script>
import FitFeaturesIcon from './FitFeaturesIcon'
const id = 'FitFeaturesControl'
export default {
components: { FitFeaturesIcon },
data: () => ({
id
})
}
export class CFitFeaturesControl {
onAdd(map) {
this._map = map
this._container = document.getElementById(id)
return this._container
}
}
</script>
0๐
I tried to to the same thing โ use a Vue Component inside the MapBox Control. I had difficulties getting other solutions to work, so I eventually cooked up my own thing. This is far from perfect and I am sure there are better solutions to this.
I create a temporary Vue Instance that is used to render the component, in my case an icon (https://oh-vue-icons.js.org). The resulting DOM element is then returned and used by MapBox. My solution is based on this codepen.
import { createApp, h } from "vue";
import mapboxgl from "mapbox-gl";
import { OhVueIcon } from "oh-vue-icons";
import "@/icons";
export class MapboxGLButtonControl implements mapboxgl.IControl {
icon: string;
className = "";
title = "";
eventHandler = (e: MouseEvent) => {};
activeToggle = false;
map: mapboxgl.Map | undefined = undefined;
container: HTMLDivElement | undefined = undefined;
btn: HTMLButtonElement | undefined = undefined;
constructor(
icon: string,
{
className = "",
title = "",
eventHandler = (e: MouseEvent) => {},
activeToggle = false,
}
) {
this.icon = icon;
this.className = className;
this.title = title;
this.eventHandler = eventHandler;
this.activeToggle = activeToggle;
}
onAdd(map: mapboxgl.Map) {
this.map = map;
const { title, icon, className, eventHandler, activeToggle } = this;
this.container = document.createElement("div");
this.container.className = "mapboxgl-ctrl-group mapboxgl-ctrl";
const tempApp = createApp({
render() {
this.btn = h(
"button",
{
class: "mapbox-gl-draw_ctrl-draw-btn" + " " + className,
type: "button",
title: title,
onClick: (e: MouseEvent) => {
if (activeToggle && e.target) {
this.btn.el?.classList.toggle("btn-active");
}
eventHandler(e);
},
},
h(OhVueIcon, {
name: icon,
})
);
return this.btn;
},
});
const mountedApp = tempApp.mount(this.container);
return this.container;
}
onRemove() {
if (this.container && this.container.parentNode) {
this.container.parentNode.removeChild(this.container);
}
this.map = undefined;
this.container = undefined;
this.btn = undefined;
}
}
Source:stackexchange.com