我在生产网站上使用 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 一起工作吗?
我刚刚致力于将传单与 Nuxt 3 集成。
自从您的问题最初发布以来,Nuxt 3 特定的传单模块已经发布:https://nuxt.com/modules/leaflet
您可以安装一个插件来使用传单标记聚类器:https://leaflet.nuxtjs.org/guide/marker-cluster.html
我建议的步骤是:
npx nuxi@latest module add @nuxtjs/leaflet
npm install leaflet.markercluster
export default defineNuxtConfig({
modules: ['@nuxtjs/leaflet'],
leaflet: {
markerCluster: 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="&copy; <a href="https://www.openstreetmap.org/">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>
我希望这有帮助:)