diff --git a/dev/serve.vue b/dev/serve.vue index ed11713..ccb8713 100644 --- a/dev/serve.vue +++ b/dev/serve.vue @@ -28,7 +28,7 @@ (this.markerCoordinates = [ 13.377507, 42.516267 ]), 5000); - // setInterval(() => (this.geoJsonSource.show = !this.geoJsonSource.show), 1000); + setInterval(() => (this.geoJsonSource.show.value = !this.geoJsonSource.show.value), 1000); } }); diff --git a/package.json b/package.json index 26ac377..6780035 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "vue-maplibre-gl", - "version": "1.0.0-beta.21", + "version": "1.0.0-beta.22", "description": "Vue 3 plugin for maplibre-gl", "keywords": [ "vue", diff --git a/src/components/layers/background.layer.ts b/src/components/layers/background.layer.ts index 4eedb30..db37a46 100644 --- a/src/components/layers/background.layer.ts +++ b/src/components/layers/background.layer.ts @@ -1,6 +1,6 @@ import { BackgroundLayer, BackgroundLayout, BackgroundPaint } from 'maplibre-gl'; import { genLayerOpts, Shared } from '@/components/layers/shared'; -import { createCommentVNode, defineComponent, inject, PropType, warn, watch } from 'vue'; +import { createCommentVNode, defineComponent, inject, onBeforeUnmount, PropType, warn, watch } from 'vue'; import { componentIdSymbol, isLoadedSymbol, mapSymbol, sourceIdSymbol, sourceLayerRegistry } from '@/components/types'; import { getSourceRef } from '@/components/sources/shared'; @@ -32,12 +32,16 @@ export default defineComponent({ } }, { immediate: true }); - registry.addUnmountHandler(() => { + function removeLayer() { if (isLoaded.value) { map.value.removeLayer(props.layerId); } - }); + } + registry.registerUnmountHandler(props.layerId, removeLayer); + onBeforeUnmount(() => { + removeLayer(); + }); }, render() { diff --git a/src/components/layers/circle.layer.ts b/src/components/layers/circle.layer.ts index 6e70aae..5a61b14 100644 --- a/src/components/layers/circle.layer.ts +++ b/src/components/layers/circle.layer.ts @@ -1,5 +1,5 @@ import { CircleLayer, CircleLayout, CirclePaint } from 'maplibre-gl'; -import { genLayerOpts, registerLayerEvents, Shared, unregisterLayerEvents } from '@/components/layers/shared'; +import { genLayerOpts, handleDispose, registerLayerEvents, Shared } from '@/components/layers/shared'; import { createCommentVNode, defineComponent, getCurrentInstance, inject, PropType, warn, watch } from 'vue'; import { componentIdSymbol, isLoadedSymbol, mapSymbol, sourceIdSymbol, sourceLayerRegistry } from '@/components/types'; import { getSourceRef } from '@/components/sources/shared'; @@ -34,12 +34,7 @@ export default defineComponent({ } }, { immediate: true }); - registry.addUnmountHandler(() => { - if (isLoaded.value) { - unregisterLayerEvents(map.value, props.layerId, ci.vnode); - map.value.removeLayer(props.layerId); - } - }); + handleDispose(isLoaded, map, ci, props, registry); }, render() { diff --git a/src/components/layers/fill.layer.ts b/src/components/layers/fill.layer.ts index 2219838..015f4fa 100644 --- a/src/components/layers/fill.layer.ts +++ b/src/components/layers/fill.layer.ts @@ -1,5 +1,5 @@ import { FillLayer, FillLayout, FillPaint } from 'maplibre-gl'; -import { genLayerOpts, registerLayerEvents, Shared, unregisterLayerEvents } from '@/components/layers/shared'; +import { genLayerOpts, handleDispose, registerLayerEvents, Shared } from '@/components/layers/shared'; import { createCommentVNode, defineComponent, getCurrentInstance, inject, PropType, warn, watch } from 'vue'; import { componentIdSymbol, isLoadedSymbol, mapSymbol, sourceIdSymbol, sourceLayerRegistry } from '@/components/types'; import { getSourceRef } from '@/components/sources/shared'; @@ -34,12 +34,7 @@ export default defineComponent({ } }, { immediate: true }); - registry.addUnmountHandler(() => { - if (isLoaded.value) { - unregisterLayerEvents(map.value, props.layerId, ci.vnode); - map.value.removeLayer(props.layerId); - } - }); + handleDispose(isLoaded, map, ci, props, registry); }, render() { diff --git a/src/components/layers/fillExtrusion.layer.ts b/src/components/layers/fillExtrusion.layer.ts index cff700c..47ea104 100644 --- a/src/components/layers/fillExtrusion.layer.ts +++ b/src/components/layers/fillExtrusion.layer.ts @@ -1,5 +1,5 @@ import { FillExtrusionLayout, FillExtrusionPaint, LineLayer } from 'maplibre-gl'; -import { genLayerOpts, registerLayerEvents, Shared, unregisterLayerEvents } from '@/components/layers/shared'; +import { genLayerOpts, handleDispose, registerLayerEvents, Shared } from '@/components/layers/shared'; import { createCommentVNode, defineComponent, getCurrentInstance, inject, PropType, warn, watch } from 'vue'; import { componentIdSymbol, isLoadedSymbol, mapSymbol, sourceIdSymbol, sourceLayerRegistry } from '@/components/types'; import { getSourceRef } from '@/components/sources/shared'; @@ -34,12 +34,7 @@ export default defineComponent({ } }, { immediate: true }); - registry.addUnmountHandler(() => { - if (isLoaded.value) { - unregisterLayerEvents(map.value, props.layerId, ci.vnode); - map.value.removeLayer(props.layerId); - } - }); + handleDispose(isLoaded, map, ci, props, registry); }, render() { diff --git a/src/components/layers/heatmap.layer.ts b/src/components/layers/heatmap.layer.ts index 7570161..622e35d 100644 --- a/src/components/layers/heatmap.layer.ts +++ b/src/components/layers/heatmap.layer.ts @@ -1,5 +1,5 @@ import { HeatmapLayer, HeatmapLayout, HeatmapPaint } from 'maplibre-gl'; -import { genLayerOpts, registerLayerEvents, Shared, unregisterLayerEvents } from '@/components/layers/shared'; +import { genLayerOpts, handleDispose, registerLayerEvents, Shared } from '@/components/layers/shared'; import { createCommentVNode, defineComponent, getCurrentInstance, inject, PropType, warn, watch } from 'vue'; import { componentIdSymbol, isLoadedSymbol, mapSymbol, sourceIdSymbol, sourceLayerRegistry } from '@/components/types'; import { getSourceRef } from '@/components/sources/shared'; @@ -34,12 +34,7 @@ export default defineComponent({ } }, { immediate: true }); - registry.addUnmountHandler(() => { - if (isLoaded.value) { - unregisterLayerEvents(map.value, props.layerId, ci.vnode); - map.value.removeLayer(props.layerId); - } - }); + handleDispose(isLoaded, map, ci, props, registry); }, render() { diff --git a/src/components/layers/hillshade.layer.ts b/src/components/layers/hillshade.layer.ts index 66c1b79..438daa6 100644 --- a/src/components/layers/hillshade.layer.ts +++ b/src/components/layers/hillshade.layer.ts @@ -1,5 +1,5 @@ import { HillshadeLayer, HillshadeLayout, HillshadePaint } from 'maplibre-gl'; -import { genLayerOpts, registerLayerEvents, Shared, unregisterLayerEvents } from '@/components/layers/shared'; +import { genLayerOpts, handleDispose, registerLayerEvents, Shared } from '@/components/layers/shared'; import { createCommentVNode, defineComponent, getCurrentInstance, inject, PropType, warn, watch } from 'vue'; import { componentIdSymbol, isLoadedSymbol, mapSymbol, sourceIdSymbol, sourceLayerRegistry } from '@/components/types'; import { getSourceRef } from '@/components/sources/shared'; @@ -34,12 +34,7 @@ export default defineComponent({ } }, { immediate: true }); - registry.addUnmountHandler(() => { - if (isLoaded.value) { - unregisterLayerEvents(map.value, props.layerId, ci.vnode); - map.value.removeLayer(props.layerId); - } - }); + handleDispose(isLoaded, map, ci, props, registry); }, render() { diff --git a/src/components/layers/line.layer.ts b/src/components/layers/line.layer.ts index 1caff26..7540f2f 100644 --- a/src/components/layers/line.layer.ts +++ b/src/components/layers/line.layer.ts @@ -1,5 +1,5 @@ import { LineLayer, LineLayout, LinePaint } from 'maplibre-gl'; -import { genLayerOpts, registerLayerEvents, Shared, unregisterLayerEvents } from '@/components/layers/shared'; +import { genLayerOpts, handleDispose, registerLayerEvents, Shared } from '@/components/layers/shared'; import { createCommentVNode, defineComponent, getCurrentInstance, inject, PropType, warn, watch } from 'vue'; import { componentIdSymbol, isLoadedSymbol, mapSymbol, sourceIdSymbol, sourceLayerRegistry } from '@/components/types'; import { getSourceRef } from '@/components/sources/shared'; @@ -34,12 +34,7 @@ export default defineComponent({ } }, { immediate: true }); - registry.addUnmountHandler(() => { - if (isLoaded.value) { - unregisterLayerEvents(map.value, props.layerId, ci.vnode); - map.value.removeLayer(props.layerId); - } - }); + handleDispose(isLoaded, map, ci, props, registry); }, render() { diff --git a/src/components/layers/raster.layer.ts b/src/components/layers/raster.layer.ts index 5dbb100..50f92e0 100644 --- a/src/components/layers/raster.layer.ts +++ b/src/components/layers/raster.layer.ts @@ -1,5 +1,5 @@ import { RasterLayer, RasterLayout, RasterPaint } from 'maplibre-gl'; -import { genLayerOpts, registerLayerEvents, Shared, unregisterLayerEvents } from '@/components/layers/shared'; +import { genLayerOpts, handleDispose, registerLayerEvents, Shared } from '@/components/layers/shared'; import { createCommentVNode, defineComponent, getCurrentInstance, inject, PropType, warn, watch } from 'vue'; import { componentIdSymbol, isLoadedSymbol, mapSymbol, sourceIdSymbol, sourceLayerRegistry } from '@/components/types'; import { getSourceRef } from '@/components/sources/shared'; @@ -34,12 +34,7 @@ export default defineComponent({ } }, { immediate: true }); - registry.addUnmountHandler(() => { - if (isLoaded.value) { - unregisterLayerEvents(map.value, props.layerId, ci.vnode); - map.value.removeLayer(props.layerId); - } - }); + handleDispose(isLoaded, map, ci, props, registry); }, render() { diff --git a/src/components/layers/shared.ts b/src/components/layers/shared.ts index ad18d14..7571ac9 100644 --- a/src/components/layers/shared.ts +++ b/src/components/layers/shared.ts @@ -1,5 +1,7 @@ -import { defineComponent, PropType, unref, VNode } from 'vue'; +import { defineComponent, onBeforeUnmount, PropType, Ref, unref, VNode } from 'vue'; import { AnySourceData, BackgroundLayer, Layer, Map, MapLayerEventType } from 'maplibre-gl'; +import { ComponentInternalInstance } from '@vue/runtime-core'; +import { SourceLayerRegistry } from '@/components/sources/sourceLayer.registry'; const sourceOpts: Array & { sourceLayer?: string })> = [ 'metadata', 'ref', 'source', 'sourceLayer', 'minzoom', 'maxzoom', 'interactive', 'filter', 'layout', 'paint' @@ -64,3 +66,18 @@ export function unregisterLayerEvents(map: Map, layerId: string, vn: VNode) { } } } + +export function handleDispose(isLoaded: Ref, map: Ref, ci: ComponentInternalInstance, props: { layerId: string }, registry: SourceLayerRegistry) { + function removeLayer() { + if (isLoaded.value) { + unregisterLayerEvents(map.value, props.layerId, ci.vnode); + map.value.removeLayer(props.layerId); + } + } + + registry.registerUnmountHandler(props.layerId, removeLayer); + onBeforeUnmount(() => { + registry.unregisterUnmountHandler(props.layerId); + removeLayer(); + }); +} diff --git a/src/components/layers/smybol.layer.ts b/src/components/layers/smybol.layer.ts index 1e48bda..2add68c 100644 --- a/src/components/layers/smybol.layer.ts +++ b/src/components/layers/smybol.layer.ts @@ -1,5 +1,5 @@ import { SymbolLayer, SymbolLayout, SymbolPaint } from 'maplibre-gl'; -import { genLayerOpts, registerLayerEvents, Shared, unregisterLayerEvents } from '@/components/layers/shared'; +import { genLayerOpts, handleDispose, registerLayerEvents, Shared } from '@/components/layers/shared'; import { createCommentVNode, defineComponent, getCurrentInstance, inject, PropType, warn, watch } from 'vue'; import { componentIdSymbol, isLoadedSymbol, mapSymbol, sourceIdSymbol, sourceLayerRegistry } from '@/components/types'; import { getSourceRef } from '@/components/sources/shared'; @@ -34,12 +34,7 @@ export default defineComponent({ } }, { immediate: true }); - registry.addUnmountHandler(() => { - if (isLoaded.value) { - unregisterLayerEvents(map.value, props.layerId, ci.vnode); - map.value.removeLayer(props.layerId); - } - }); + handleDispose(isLoaded, map, ci, props, registry); }, render() { diff --git a/src/components/sources/shared.ts b/src/components/sources/shared.ts index bfcb6dc..563638f 100644 --- a/src/components/sources/shared.ts +++ b/src/components/sources/shared.ts @@ -44,6 +44,7 @@ export function bindSource(map: Ref, emitter.on('styleSwitched', resetSource); return onBeforeUnmount(() => { + console.log('UMOUNT SOURC') if (isLoaded.value) { registry.unmount(); map.value.removeSource(props.sourceId); diff --git a/src/components/sources/sourceLayer.registry.ts b/src/components/sources/sourceLayer.registry.ts index 957dc57..dd5cdfe 100644 --- a/src/components/sources/sourceLayer.registry.ts +++ b/src/components/sources/sourceLayer.registry.ts @@ -2,16 +2,18 @@ export type SourceLayerRegistryHandler = () => void export class SourceLayerRegistry { - private unmountHandlers: SourceLayerRegistryHandler[] = []; + private unmountHandlers = new Map(); - addUnmountHandler(handler: SourceLayerRegistryHandler) { - this.unmountHandlers.push(handler); + registerUnmountHandler(id: string, handler: SourceLayerRegistryHandler) { + this.unmountHandlers.set(id, handler); + } + + unregisterUnmountHandler(id: string) { + this.unmountHandlers.delete(id); } unmount() { - for (let i = 0, len = this.unmountHandlers.length; i < len; i++) { - this.unmountHandlers[ i ](); - } + this.unmountHandlers.forEach((h) => h()); } }