Skip to content

Commit 56b386d

Browse files
committed
refactor(ol-source-*): move common setup into useSource composable
All source components are using the `useSource` composable now. This refactoring won't affect you most likely but in case you used some undocumented exposed APIs/features it will. BREAKING CHANGE: The created Source class from the corresponding OpenLayers source isn't wrapped in a computed anymore but in a shallowRef. This will improve the performance and prevent unneeded re-computations. Also, the provided `imageLayer` references is now wrapped in a `Ref` which will make it reactive: In case the layer changes, the source is updated and applied to the changed layers reference. This behavior was already default for all layer types: ```diff -const layer = inject<ImageLayer<Static> | null>("imageLayer"); +const layer = inject<Ref<ImageLayer<Static>> | null>("imageLayer"); ``` closes: #354
1 parent 6dd3fa1 commit 56b386d

34 files changed

+337
-865
lines changed

Diff for: docs/pluginsguide/index.md

+7-23
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,8 @@ The example below demonstrates how a source called `FooSource` could be implemen
7272
7373
<script setup lang="ts">
7474
import type { Ref } from "vue";
75-
import { inject, watch, onMounted, onUnmounted, shallowRef } from "vue";
75+
import { inject } from "vue";
76+
import { useSource } from "vue3-openlayers";
7677
7778
// import the source to be wrapped in a component.
7879
import FooSource, { type Options } from "foo-source";
@@ -96,28 +97,11 @@ const layer = inject<Ref<TileLayer<FooSource>> | null>("tileLayer");
9697
// const layer = inject<Ref<VectorLayer<FooSource>> | null>("vectorLayer");
9798
// const layer = inject<Ref<HeatmapLayer> | null>("heatmapLayer");
9899
99-
// Store a shallowRef of the Source, so it can be watched for changes.
100-
const source = shallowRef(new FooSource(props));
101-
102-
// Watch for source changes and re-apply the source to the layer.
103-
watch(source, () => {
104-
layer?.value?.setSource(source.value);
105-
});
106-
107-
// Watch for layer changes and re-apply the source to the layer.
108-
watch(layer, () => {
109-
layer?.value?.setSource(source.value);
110-
});
111-
112-
// Apply the source once the component is mounted.
113-
onMounted(() => {
114-
layer?.value?.setSource(source.value);
115-
});
116-
117-
// Cleanup when component is destroyed.
118-
onUnmounted(() => {
119-
layer?.value?.setSource(null);
120-
});
100+
// Create the source and watch for changes of the source, the props or the parent layer.
101+
// Changes will be applied and the source will be removed on unmount.
102+
// The last parameter will receive the event names which should be handled by the target component.
103+
// Check out the sources of the composable for more details.
104+
const { source } = useSource(FooSource, layer, props, ["removefeature"]);
121105
122106
// Expose the layer and source, so it can be used as a `ref=""` on the element
123107
defineExpose({

Diff for: src/components/layers/OlImageLayer.vue

+2-2
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,9 @@ const properties = usePropsAsObjectProperties(props);
2424
const imageLayer = shallowRef(new ImageLayer(properties));
2525
useLayer(imageLayer, properties);
2626
27-
provide("imageLayer", imageLayer.value);
27+
provide("imageLayer", imageLayer);
2828
2929
defineExpose({
30-
imageLayer: imageLayer.value,
30+
imageLayer,
3131
});
3232
</script>

Diff for: src/components/map/__test__/OlFeature.spec.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ describe("OlMap.vue", () => {
1919
},
2020
global: {
2121
provide: {
22-
"ol-options": { debug: true },
22+
"ol-options": { debug: false },
2323
vectorSource,
2424
},
2525
},

Diff for: src/components/map/__test__/OlMap.spec.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ describe("OlMap.vue", () => {
1111
},
1212
global: {
1313
provide: {
14-
"ol-options": { debug: true },
14+
"ol-options": { debug: false },
1515
},
1616
},
1717
});

Diff for: src/components/map/__test__/OlOverlay.spec.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ describe("OlOverlay.vue", () => {
1515
},
1616
global: {
1717
provide: {
18-
"ol-options": { debug: true },
18+
"ol-options": { debug: false },
1919
map,
2020
},
2121
},

Diff for: src/components/sources/OlSourceBingMaps.vue

+10-34
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,10 @@
55
<script setup lang="ts">
66
import BingMaps, { type Options } from "ol/source/BingMaps";
77
import type { Ref } from "vue";
8-
import { inject, watch, onMounted, onUnmounted, computed } from "vue";
8+
import { inject } from "vue";
99
import type TileLayer from "ol/layer/Tile";
10-
import usePropsAsObjectProperties from "@/composables/usePropsAsObjectProperties";
11-
import {
12-
IMAGE_SOURCE_EVENTS,
13-
useOpenLayersEvents,
14-
} from "@/composables/useOpenLayersEvents";
10+
import { IMAGE_SOURCE_EVENTS } from "@/composables/useOpenLayersEvents";
11+
import useSource from "@/composables/useSource";
1512
1613
// prevent warnings caused by event pass-through via useOpenLayersEvents composable
1714
defineOptions({
@@ -22,37 +19,16 @@ const props = defineProps<Omit<Options, "key"> & { apiKey: string }>();
2219
2320
const layer = inject<Ref<TileLayer<BingMaps>> | null>("tileLayer");
2421
25-
const properties = usePropsAsObjectProperties(props);
26-
27-
const source = computed(
28-
() =>
29-
new BingMaps({
30-
...properties,
31-
key: properties.apiKey,
32-
}),
33-
);
34-
35-
useOpenLayersEvents(source, IMAGE_SOURCE_EVENTS);
36-
37-
watch(source, () => {
38-
layer?.value?.setSource(source.value);
39-
});
40-
41-
watch(
42-
() => layer?.value,
43-
() => {
44-
layer?.value?.setSource(source.value);
22+
const { source } = useSource(
23+
BingMaps,
24+
layer,
25+
{
26+
...props,
27+
key: props.apiKey,
4528
},
29+
IMAGE_SOURCE_EVENTS,
4630
);
4731
48-
onMounted(() => {
49-
layer?.value?.setSource(source.value);
50-
});
51-
52-
onUnmounted(() => {
53-
layer?.value?.setSource(null);
54-
});
55-
5632
defineExpose({
5733
layer,
5834
source,

Diff for: src/components/sources/OlSourceBingmaps.vue

+10-34
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,10 @@
55
<script setup lang="ts">
66
import BingMaps, { type Options } from "ol/source/BingMaps";
77
import type { Ref } from "vue";
8-
import { inject, watch, onMounted, onUnmounted, computed } from "vue";
8+
import { inject } from "vue";
99
import type TileLayer from "ol/layer/Tile";
10-
import usePropsAsObjectProperties from "@/composables/usePropsAsObjectProperties";
11-
import {
12-
IMAGE_SOURCE_EVENTS,
13-
useOpenLayersEvents,
14-
} from "@/composables/useOpenLayersEvents";
10+
import { IMAGE_SOURCE_EVENTS } from "@/composables/useOpenLayersEvents";
11+
import useSource from "@/composables/useSource";
1512
1613
// prevent warnings caused by event pass-through via useOpenLayersEvents composable
1714
defineOptions({
@@ -22,37 +19,16 @@ const props = defineProps<Omit<Options, "key"> & { apiKey: string }>();
2219
2320
const layer = inject<Ref<TileLayer<BingMaps>> | null>("tileLayer");
2421
25-
const properties = usePropsAsObjectProperties(props);
26-
27-
const source = computed(
28-
() =>
29-
new BingMaps({
30-
...properties,
31-
key: properties.apiKey,
32-
}),
33-
);
34-
35-
useOpenLayersEvents(source, IMAGE_SOURCE_EVENTS);
36-
37-
watch(source, () => {
38-
layer?.value?.setSource(source.value);
39-
});
40-
41-
watch(
42-
() => layer?.value,
43-
() => {
44-
layer?.value?.setSource(source.value);
22+
const { source } = useSource(
23+
BingMaps,
24+
layer,
25+
{
26+
...props,
27+
key: props.apiKey,
4528
},
29+
IMAGE_SOURCE_EVENTS,
4630
);
4731
48-
onMounted(() => {
49-
layer?.value?.setSource(source.value);
50-
});
51-
52-
onUnmounted(() => {
53-
layer?.value?.setSource(null);
54-
});
55-
5632
defineExpose({
5733
layer,
5834
source,

Diff for: src/components/sources/OlSourceCluster.vue

+4-36
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,12 @@
77
<script setup lang="ts">
88
import Cluster, { type Options } from "ol/source/Cluster";
99
import type { Ref } from "vue";
10-
import { inject, watch, onMounted, onUnmounted, provide, computed } from "vue";
10+
import { inject, provide } from "vue";
1111
import type Geometry from "ol/geom/Geometry";
1212
import type Feature from "ol/Feature";
1313
import type Point from "ol/geom/Point";
14-
import usePropsAsObjectProperties from "@/composables/usePropsAsObjectProperties";
15-
import {
16-
FEATURE_EVENTS,
17-
useOpenLayersEvents,
18-
} from "@/composables/useOpenLayersEvents";
14+
import { FEATURE_EVENTS } from "@/composables/useOpenLayersEvents";
15+
import useSource from "@/composables/useSource";
1916
2017
// prevent warnings caused by event pass-through via useOpenLayersEvents composable
2118
defineOptions({
@@ -31,36 +28,7 @@ const props = withDefaults(defineProps<Options>(), {
3128
3229
const layer = inject<Ref<Cluster> | null>("vectorLayer");
3330
34-
const properties = usePropsAsObjectProperties(props);
35-
36-
const source = computed(() => new Cluster(properties));
37-
38-
useOpenLayersEvents(source, FEATURE_EVENTS);
39-
40-
const applySource = () => {
41-
layer?.value?.setSource(null);
42-
layer?.value?.setSource(source.value);
43-
layer?.value?.changed();
44-
};
45-
watch(properties, () => {
46-
applySource();
47-
});
48-
49-
watch(
50-
() => layer?.value,
51-
() => {
52-
applySource();
53-
},
54-
);
55-
56-
onMounted(() => {
57-
layer?.value?.setSource(source.value);
58-
layer?.value?.changed();
59-
});
60-
61-
onUnmounted(() => {
62-
layer?.value?.setSource(null);
63-
});
31+
const { source } = useSource(Cluster, layer, props, FEATURE_EVENTS);
6432
6533
provide("vectorLayer", source);
6634

Diff for: src/components/sources/OlSourceGeoTIFF.vue

+4-33
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,10 @@
44

55
<script setup lang="ts">
66
import GeoTIFF, { type Options } from "ol/source/GeoTIFF";
7-
import { inject, onMounted, onUnmounted, watch, type Ref } from "vue";
8-
import usePropsAsObjectProperties from "@/composables/usePropsAsObjectProperties";
7+
import { inject, type Ref } from "vue";
98
import type TileLayer from "ol/layer/Tile";
10-
import projectionFromProperties from "@/helpers/projection";
11-
import {
12-
TILE_SOURCE_EVENTS,
13-
useOpenLayersEvents,
14-
} from "@/composables/useOpenLayersEvents";
15-
import type { ProjectionLike } from "ol/proj";
9+
import { TILE_SOURCE_EVENTS } from "@/composables/useOpenLayersEvents";
10+
import useSource from "@/composables/useSource";
1611
1712
// prevent warnings caused by event pass-through via useOpenLayersEvents composable
1813
defineOptions({
@@ -22,32 +17,8 @@ defineOptions({
2217
const props = defineProps<Options>();
2318
2419
const layer = inject<Ref<TileLayer<GeoTIFF>> | null>("tileLayer");
25-
const properties = usePropsAsObjectProperties(props);
2620
27-
const createSource = () =>
28-
new GeoTIFF({
29-
...properties,
30-
projection: projectionFromProperties(
31-
properties.projection as ProjectionLike,
32-
),
33-
});
34-
35-
let source = createSource();
36-
37-
useOpenLayersEvents(source, TILE_SOURCE_EVENTS);
38-
39-
watch(properties, () => {
40-
layer?.value.setSource(null);
41-
source = createSource();
42-
layer?.value.setSource(source);
43-
});
44-
onMounted(() => {
45-
layer?.value.setSource(source);
46-
});
47-
48-
onUnmounted(() => {
49-
layer?.value.setSource(null);
50-
});
21+
const { source } = useSource(GeoTIFF, layer, props, TILE_SOURCE_EVENTS);
5122
5223
defineExpose({
5324
layer,

Diff for: src/components/sources/OlSourceGeoTiff.vue

+4-33
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,10 @@
44

55
<script setup lang="ts">
66
import GeoTIFF, { type Options } from "ol/source/GeoTIFF";
7-
import { inject, onMounted, onUnmounted, watch, type Ref } from "vue";
8-
import usePropsAsObjectProperties from "@/composables/usePropsAsObjectProperties";
7+
import { inject, type Ref } from "vue";
98
import type TileLayer from "ol/layer/Tile";
10-
import projectionFromProperties from "@/helpers/projection";
11-
import {
12-
TILE_SOURCE_EVENTS,
13-
useOpenLayersEvents,
14-
} from "@/composables/useOpenLayersEvents";
15-
import type { ProjectionLike } from "ol/proj";
9+
import { TILE_SOURCE_EVENTS } from "@/composables/useOpenLayersEvents";
10+
import useSource from "@/composables/useSource";
1611
1712
// prevent warnings caused by event pass-through via useOpenLayersEvents composable
1813
defineOptions({
@@ -22,32 +17,8 @@ defineOptions({
2217
const props = defineProps<Options>();
2318
2419
const layer = inject<Ref<TileLayer<GeoTIFF>> | null>("tileLayer");
25-
const properties = usePropsAsObjectProperties(props);
2620
27-
const createSource = () =>
28-
new GeoTIFF({
29-
...properties,
30-
projection: projectionFromProperties(
31-
properties.projection as ProjectionLike,
32-
),
33-
});
34-
35-
let source = createSource();
36-
37-
useOpenLayersEvents(source, TILE_SOURCE_EVENTS);
38-
39-
watch(properties, () => {
40-
layer?.value.setSource(null);
41-
source = createSource();
42-
layer?.value.setSource(source);
43-
});
44-
onMounted(() => {
45-
layer?.value.setSource(source);
46-
});
47-
48-
onUnmounted(() => {
49-
layer?.value.setSource(null);
50-
});
21+
const { source } = useSource(GeoTIFF, layer, props, TILE_SOURCE_EVENTS);
5122
5223
defineExpose({
5324
layer,

0 commit comments

Comments
 (0)