如何在Mapbox IControl中使用Vue组件

chhqkbe1  于 2023-03-24  发布在  Vue.js
关注(0)|答案(2)|浏览(181)

我想在MapBox控件中使用Vue,而不是使用旧的DOM API。

bf1o4zei

bf1o4zei1#

<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>
4bbkushb

4bbkushb2#

我也试过同样的方法-在MapBox控件中使用Vue组件。我很难让其他解决方案工作,所以我最终想出了自己的方法。这远非完美,我相信有更好的解决方案。
我创建了一个临时的Vue示例,用于呈现组件,在我的例子中是一个图标(https://oh-vue-icons.js.org),然后返回生成的DOM元素并由MapBox使用。

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;

        // no idea why this has to be done, but it does what it should
        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;
    }
}

相关问题