将 leaflet.markercluster 与 Nuxt 3 应用程序一起使用

问题描述 投票:0回答:1

我在生产网站上使用 Leaflet 和 Nuxt3、TypeScript 和 Composition API。 随着我们获得越来越多的标记,我想使用 leaflet.markercluster 但我不知道如何使其正常工作

这是我的设置:

leaflet.client.ts

import {
  LIcon,
  LMap,
  LMarker,
  LPopup,
  LTileLayer,
} from "@vue-leaflet/vue-leaflet";
import L from "leaflet";

export default defineNuxtPlugin((nuxtApp) => {
  nuxtApp.vueApp.component("LMap", LMap);
  nuxtApp.vueApp.component("LTileLayer", LTileLayer);
  nuxtApp.vueApp.component("LMarker", LMarker);
  nuxtApp.vueApp.component("LIcon", LIcon);
  nuxtApp.vueApp.component("LPopup", LPopup);

  return {
    provide: {
      L,
    },
  };
});

Map.vue

<client-only>
   <l-map 
       ref="locationsMap"
       :min-zoom="leafletOptions.minZoom"
       :max-zoom="leafletOptions.maxZoom"
       :zoom-animation="true"
       :zoom="leafletOptions.zoom"
       :center="leafletOptions.center"
       :useGlobalLeaflet="false"
       :options="{ tap: false }"
       @ready="onLeafletReady">
         <l-tile-layer :url="leafletOptions.url"/>
           <template v-for="location in locations"
                     :key="location.id">
             <l-marker
                :lat-lng="[location.attributes.lat, location.attributes.long]"
                v-if="location.attributes.active">
                  <div v-if="location.attributes.lat && location.attributes.long">
                    <l-popup class="text-center flex flex-col gap-y-4">
                     ...
                    </l-popup>
                    <l-icon>
                      ...
                    </l-icon>
                  </div>
              </l-marker>
            </template>
       </l-map>
        ...
</client-only>

<script setup lang="ts">
import {LIcon, LMap, LMarker, LPopup, LTileLayer} from "@vue-leaflet/vue-leaflet";
import "leaflet/dist/leaflet.css";

const leafletOptions = ref({
  url: "https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png",
  minZoom: 5,
  maxZoom: 13,
  zoom: 5.5,
  map: null,
  center: [47.040182, 2.536054],
  bounds: null,
  overlayLocation: false,
  colors: ["#ED722E", "#F6BE00", "#979B0B", "#DA2C81"],
});

// Setup and api calls to get locations
</script>

package.json

{
 ...,
 "depencencies": {
   "@vue-leaflet/vue-leaflet": "^0.7.0",
   "leaflet": "^1.9.3",
   "leaflet.markercluster": "^1.5.3",
 },
 "devDependencies": {
   "nuxt": "^3.0.0",
   "typescript": "^4.9.4"
   "@types/leaflet.markercluster": "^1.5.1",
 }
}

问题是,现在我尝试通过添加

leaflet.markercluster
对标记进行分组。所以我添加了这样的东西:

leaflet.client.ts

...
import "leaflet.markercluster";
import "leaflet.markercluster/dist/MarkerCluster.css";
import "leaflet.markercluster/dist/MarkerCluster.Default.css";

export default defineNuxtPlugin((nuxtApp) => {
  ...

  return {
    provide: {
      L,
    },
  };
});

但现在我不知道下一步该做什么。按照官方文档所述使用

L.markerClusterGroup()
不起作用,因为我们在使用 ssr 的客户端方法时收到 500 错误。

我还尝试使用 import 直接导入我的组件:

Map.vue

import { MarkerClusterGroup } from 'leaflet.markercluster';

const markersGroup = ref(null);

...

const onLeafletReady = async () => {
  markersGroup.value = new MarkerClusterGroup() // NOT WORKING
  await nextTick();
  leafletObject.value = locationsMap.value;
  leafletReady.value = true;

  leafletObject.value.addLayer(markersGroup.value)
}

但是我们遇到了与使用

L.anyMethod()
相同的问题,出现 500 错误。

我在这个问题上看到Sam85安装了该软件包,但这不是同一个问题。 :/

有人尝试过让它与 Nuxt 3 一起工作吗?

leaflet nuxt3.js leaflet.markercluster
1个回答
0
投票

我刚刚致力于将传单与 Nuxt 3 集成。

自从您的问题最初发布以来,Nuxt 3 特定的传单模块已经发布:https://nuxt.com/modules/leaflet

您可以安装一个插件来使用传单标记聚类器:https://leaflet.nuxtjs.org/guide/marker-cluster.html

我建议的步骤是:

  1. 安装 Nuxt Leaflet -
    npx nuxi@latest module add @nuxtjs/leaflet
  2. 安装标记集群 -
    npm install leaflet.markercluster
  3. 更新您的 nuxt 配置以激活插件:
export default defineNuxtConfig({
  modules: ['@nuxtjs/leaflet'],
  leaflet: {
    markerCluster: true
  }
})
  1. 加载地图对象时调用 useLMarkerCluster (注意 @ready 和 :use-global-leaflet="true"):
<template>
  <div style="height:100vh; width:100vw">
    <h1>Marker Cluster</h1>
    <LMap
      ref="map"
      :zoom="6"
      :max-zoom="18"
      :center="[47.21322, -1.559482]"
      :use-global-leaflet="true"
      @ready="onMapReady"
    >
      <LTileLayer
        url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
        attribution="&amp;copy; <a href=&quot;https://www.openstreetmap.org/&quot;>OpenStreetMap</a> contributors"
        layer-type="base"
        name="OpenStreetMap"
      />
    </LMap>
  </div>
</template>

<script setup lang="ts">
import L from 'leaflet'
import { ref } from 'vue';

const map = ref(null) as any;

// Create locations data (20 locations around Nantes)
const locations = [
  { name: 'Nantes', lat: 47.218371, lng: -1.553621 },
  { name: 'Saint-Nazaire', lat: 47.273018, lng: -2.213733 },
  { name: 'La Baule', lat: 47.286835, lng: -2.393108 },
];

// When the map is ready
const onMapReady = () => {
  useLMarkerCluster({
    leafletObject: map.value.leafletObject,
    markers: locations
  });
}
</script>

我希望这有帮助:)

© www.soinside.com 2019 - 2024. All rights reserved.