如何将自定义 Vue 组件挂载到 L.markerClusterGroup 的标记

How to mount custom Vue component to markers for L.markerClusterGroup

我需要在 Vue 组件中使用自定义弹出窗口呈现自定义标记。

我使用 L.markerClusterGroup 并尝试为标记和弹出窗口安装自定义组件,但它不起作用。

map.js

<template>
  <div id="map" class="map"></div>
</template>

<script>
import L from 'mapbox.js';
import 'mapbox.js/dist/mapbox.css';
import 'leaflet.markercluster';

import Vue from 'vue';
import Pin from './Pin';
import Popup from './Popup';
import config from '@/config';

const EnhancedPin = Vue.extend(Pin);
const EnhancedPopup = Vue.extend(Popup);

export default {
  props: {
    geojson: {
      type: Object,
      required: true,
    },
  },
  mounted() {
    this.initMap();
  },
  methods: {
    initMap() {
      this.createMap(this.geojson);

      this.addClustersToMap(this.geojson);
    },
    createMap(geojson) {
      L.mapbox.accessToken = config.mapBoxKey;

      this.map = L.mapbox
        .map('map', null, {
          attributionControl: { compact: false },
          zoomControl: true,
          minZoom: 1,
        })
        .addLayer(L.mapbox.styleLayer('mapbox://styles/mapbox/streets-v11'));
        .setView([0, 0], 2);
    },
    addClustersToMap(geojson) {
      var clusterGroup = L.markerClusterGroup({
        showCoverageOnHover: false,
        iconCreateFunction: cluster => {
          return L.divIcon({
            className: 'cluster-icon',
            iconSize: 40,
            html: cluster.getChildCount(),
          });
        },
      });

      geojson.features.forEach(feature => {
        var cssIcon = L.divIcon({
          className: 'icon',
          html: '<div class="icon-inner"></div>',
        });
        const popup = L.popup({ minWidth: 220 }).setContent('<div class="popup-inner"></div>');

        const marker = L.marker([feature.geometry.coordinates[1], feature.geometry.coordinates[0]]);

        marker.setIcon(cssIcon).bindPopup(popup);

        clusterGroup.addLayer(marker);

        new EnhancedPin({
          propsData: {
            item: feature,
          },
        }).$mount('.icon-inner');

        marker.on('click', e => {
          setTimeout(() => {
            new EnhancedPopup({
              propsData: {
                item: feature,
              },
            }).$mount('.popup-inner');
          });
        });
      });

      this.map.addLayer(clusterGroup);
    },
  },
};
</script>

<style>
.cluster-icon {
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--primary);
  border-radius: 50%;
  box-shadow: 0 0 0 3px rgba(48, 72, 107, 0.3);
  color: var(--white);
  font-size: 1em;
  font-weight: bold;
}
</style>

我在控制台中遇到错误

[Vue warn]: Cannot find element: .icon-inner

因为 .icon-inner 在 DOM 中不存在。

如何使用 Vue 组件作为标记?需要在缩放和移动地图时起作用。

通常 "trick" 在 Leaflet 地图中使用 Vue 组件只是 render them off-document 并将生成的 $el HTMLElement 传递给 Leaflet 来处理:

const myIconVueEl = new EnhancedPin(myPinData).$mount().$el; // no selector to mount into

const myIcon = L.divIcon({
  html: myIconVueEl.outerHTML // directly pass an HTMLElement
});

const myPopupVueEl = new EnhancedPopup(myPopupData).$mount().$el;

const marker = L.marker(latLng, {
  icon: myIcon
}).bindPopup(myPopupVueEl);