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

时间:2019-07-11 14:50:51

标签: vue.js leaflet leaflet.markercluster

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

map

我使用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组件作为标记?缩放和移动地图时,它需要工作。

1 个答案:

答案 0 :(得分:0)

在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);