Skip to content

Commit aef9142

Browse files
committed
feat: support multi map in a same page
1 parent cd6390e commit aef9142

17 files changed

+334
-135
lines changed

cspell.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
"dictionaryDefinitions": [],
55
"dictionaries": [],
66
"words": [
7+
"latlng",
8+
"latlngs",
79
"Tilelayer"
810
],
911
"ignoreWords": [],

examples/Layout.vue

Lines changed: 95 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -6,57 +6,100 @@ import {
66
LTooltip,
77
LPopup,
88
LCircle,
9-
LPolygon
9+
LCircleMarker,
10+
LPolygon,
11+
LPolyline,
12+
LRectangle,
1013
} from '../src';
1114
import '../node_modules/leaflet/dist/leaflet.css';
1215
16+
const mapOptions = {
17+
zoom: 13,
18+
center: { lat: 51.505, lng: -0.09 },
19+
minZoom: 8,
20+
maxZoom: 15,
21+
attributionControl: true,
22+
zoomControl: true
23+
}
24+
25+
const tileLayerOptions = {
26+
attribution: 'vue-leaflet',
27+
maxZoom: 18,
28+
id: 'mapbox/streets-v11',
29+
tileSize: 512,
30+
zoomOffset: -1,
31+
accessToken: 'pk.eyJ1IjoieHdwaXNtZSIsImEiOiJ5cTlCQTlRIn0.QdV-wNUKbgs7jAlbVE747Q'
32+
}
33+
1334
</script>
1435

1536
<template>
16-
<l-map id="map1" :options="{
17-
zoom: 13,
18-
center: { lat: 51.505, lng: -0.09 },
19-
minZoom: 8,
20-
maxZoom: 15,
21-
attributionControl: true,
22-
zoomControl: true
23-
}">
24-
<l-tilelayer urlTemplate="https://api.mapbox.com/styles/v1/{id}/tiles/{z}/{x}/{y}?access_token={accessToken}"
25-
:options="{
26-
attribution: 'vue-leaflet',
27-
maxZoom: 18,
28-
id: 'mapbox/streets-v11',
29-
tileSize: 512,
30-
zoomOffset: -1,
31-
accessToken: 'pk.eyJ1IjoieHdwaXNtZSIsImEiOiJ5cTlCQTlRIn0.QdV-wNUKbgs7jAlbVE747Q'
37+
<div>
38+
<h1>Marker/Tooltip/Popup</h1>
39+
<l-map id="map1" :options="mapOptions">
40+
<l-tilelayer urlTemplate="https://api.mapbox.com/styles/v1/{id}/tiles/{z}/{x}/{y}?access_token={accessToken}"
41+
:options="tileLayerOptions" />
42+
<l-marker id="marker1" :latlng="{ lat: 51.505, lng: -0.09 }" :options="{
43+
title: 'marker1',
44+
opacity: 1,
45+
draggable: true
46+
}">
47+
<l-tooltip :options="{ content: 'tooltip with marker1' }" />
48+
</l-marker>
49+
<l-marker id="marker2" :latlng="{ lat: 51.505, lng: -0.11 }" :options="{
50+
title: 'marker2'
51+
}">
52+
<l-popup :options="{ content: 'popup with marker2' }" />
53+
</l-marker>
54+
<l-tooltip :options="{ content: 'tooltip standalone' }" :latlng="{ lat: 51.505, lng: 0 }" />
55+
<l-popup :options="{ content: 'popup standalone' }" :latlng="{ lat: 51.505, lng: 0 }" />
56+
</l-map>
57+
</div>
58+
<div>
59+
<h1>Vector Layers</h1>
60+
<l-map id="map2" :options="mapOptions">
61+
<l-tilelayer urlTemplate="https://api.mapbox.com/styles/v1/{id}/tiles/{z}/{x}/{y}?access_token={accessToken}"
62+
:options="tileLayerOptions"/>
63+
<l-circle :latlng="[51.508, -0.11]" :options="{
64+
color: 'red',
65+
fillColor: '#f03',
66+
fillOpacity: 0.5,
67+
radius: 500
3268
}" />
33-
<l-marker :latlng="{ lat: 51.505, lng: -0.09 }" :options="{
34-
title: 'marker1',
35-
opacity: 1,
36-
draggable: true
37-
}">
38-
<l-tooltip :options="{ content: 'tooltip with marker1' }" />
39-
</l-marker>
40-
<l-marker :latlng="{ lat: 51.505, lng: -0.11 }" :options="{
41-
title: 'marker2'
42-
}">
43-
<l-popup :options="{ content: 'popup with marker2' }" />
44-
</l-marker>
45-
<l-tooltip :options="{ content: 'tooltip standalone' }" :latlng="{ lat: 51.505, lng: 0 }" />
46-
<l-popup :options="{ content: 'popup standalone' }" :latlng="{ lat: 51.505, lng: 0 }" />
47-
<l-circle :latlng="[51.508, -0.11]" :options="{
48-
color: 'red',
49-
fillColor: '#f03',
50-
fillOpacity: 0.5,
51-
radius: 500
52-
}" />
53-
<l-polygon :latlng="[
54-
[51.509, -0.08],
55-
[51.503, -0.06],
56-
[51.51, -0.047]
57-
]" />
58-
59-
</l-map>
69+
<LCircleMarker :latlng="[51.512, -0.18]" :options="{
70+
color: 'red',
71+
fillColor: '#f03',
72+
fillOpacity: 0.5,
73+
radius: 100
74+
}" />
75+
<l-polygon :latlngs="[
76+
[51.509, -0.08],
77+
[51.503, -0.06],
78+
[51.51, -0.047]
79+
]" />
80+
<l-polyline :latlngs="[
81+
[51.510, -0.09],
82+
[51.505, -0.07],
83+
[51.56, -0.048]
84+
]" />
85+
<l-rectangle :latLngBounds="[
86+
[51.510, -0.09],
87+
[51.505, -0.07],
88+
]" />
89+
</l-map>
90+
</div>
91+
<div>
92+
<h1>Control</h1>
93+
<l-map id="map3" :options="mapOptions">
94+
<l-tilelayer urlTemplate="https://api.mapbox.com/styles/v1/{id}/tiles/{z}/{x}/{y}?access_token={accessToken}"
95+
:options="tileLayerOptions" />
96+
<!-- <l-marker id="marker3" :latlng="{ lat: 51.505, lng: -0.2 }" :options="{
97+
title: 'marker3'
98+
}">
99+
<l-popup :options="{ content: 'popup with marker3' }" />
100+
</l-marker> -->
101+
</l-map>
102+
</div>
60103
</template>
61104

62105

@@ -68,17 +111,20 @@ import '../node_modules/leaflet/dist/leaflet.css';
68111
height: 100%;
69112
}
70113
71-
#map1 {
72-
height: 100%;
114+
#map1,
115+
#map2,
116+
#map3 {
117+
height: 300px;
73118
}
74119
120+
html,
75121
body {
76122
padding: 0;
77123
margin: 0;
124+
height: 100%;
78125
}
79126
80-
html,
81-
body {
82-
height: 100%;
127+
h1 {
128+
padding: 0 20px;
83129
}
84130
</style>

src/components/LCircle.vue

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,32 @@
11
<script setup lang="ts">
22
import L, { CircleOptions, LatLngExpression } from 'leaflet'
3-
import { PropType, inject, nextTick } from 'vue';
3+
import { PropType, inject, nextTick, useAttrs, useSlots } from 'vue';
44
import { MapProvide } from '../core/Map';
5+
import { MAP_PROVIDE, getMapInjectKey } from '../utils/injectKey';
56
6-
const mapProvide = inject<MapProvide>('mapProvide');
77
8+
const mapProvide = inject<MapProvide>(MAP_PROVIDE);
9+
10+
const key = getMapInjectKey();
811
912
const props = defineProps({
1013
latlng: {
1114
type: Object as PropType<LatLngExpression>,
1215
required: true
1316
},
1417
options: {
15-
type: Object as PropType<CircleOptions>,
16-
required: false
17-
}
18+
type: Object as PropType<CircleOptions>,
19+
required: false
20+
}
1821
})
1922
23+
24+
2025
nextTick(() => {
2126
const circle = L.circle(props.latlng, props.options);
22-
mapProvide?.getMap()?.addLayer(circle);
27+
mapProvide?.getMap(key)?.addLayer(circle);
2328
})
2429
2530
</script>
2631

27-
<template>
28-
</template>
32+
<template></template>

src/components/LCircleMarker.vue

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
<script setup lang="ts">
2+
import L, { CircleMarkerOptions, CircleOptions, LatLngExpression } from 'leaflet'
3+
import { PropType, inject, nextTick } from 'vue';
4+
import { MapProvide } from '../core/Map';
5+
import { MAP_PROVIDE, getMapInjectKey } from '../utils/injectKey';
6+
7+
8+
const mapProvide = inject<MapProvide>(MAP_PROVIDE);
9+
10+
const key = getMapInjectKey();
11+
12+
const props = defineProps({
13+
latlng: {
14+
type: Object as PropType<LatLngExpression>,
15+
required: true
16+
},
17+
options: {
18+
type: Object as PropType<CircleMarkerOptions>,
19+
required: false
20+
}
21+
})
22+
23+
24+
25+
nextTick(() => {
26+
const circle = L.circleMarker(props.latlng, props.options);
27+
mapProvide?.getMap(key)?.addLayer(circle);
28+
})
29+
30+
</script>
31+
32+
<template></template>

src/components/LMap.vue

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { MapOptions } from 'leaflet';
44
import { provide } from 'vue'
55
import L from 'leaflet';
66
import { mapProvide } from '../core/Map';
7+
import { MAP_PROVIDE, getMapInjectKey } from '../utils/injectKey';
78
89
910
const props = defineProps({
@@ -17,11 +18,19 @@ const props = defineProps({
1718
}
1819
});
1920
20-
provide('mapProvide', mapProvide)
21+
provide(MAP_PROVIDE, mapProvide)
22+
23+
const key = getMapInjectKey(props.id);
2124
2225
onMounted(() => {
26+
console.log(props.id);
2327
const content = L.map(props.id, props.options);
24-
mapProvide.setMap(content);
28+
mapProvide.setMap(key, content);
29+
})
30+
31+
defineExpose({
32+
id: props.id,
33+
category: 'map'
2534
})
2635
2736
</script>

src/components/LMarker.vue

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import defaultIcon from 'leaflet/dist/images/marker-icon.png'
77
import defaultIconShadow from 'leaflet/dist/images/marker-shadow.png';
88
import defaultIconRetina from 'leaflet/dist/images/marker-icon-2x.png';
99
import { markerProvide } from '../core/Marker';
10+
import { MAP_PROVIDE, MARK_PROVIDE, getMapInjectKey, getMarkerInjectKey } from '../utils/injectKey';
1011
1112
const events = [
1213
'click',
@@ -29,6 +30,10 @@ const events = [
2930
3031
3132
const props = defineProps({
33+
id: {
34+
type: String,
35+
required: true,
36+
},
3237
latlng: {
3338
type: Object as PropType<LatLngExpression>,
3439
required: true,
@@ -38,17 +43,29 @@ const props = defineProps({
3843
required: false
3944
}
4045
});
41-
const mapProvide = inject<MapProvide>('mapProvide');
4246
43-
provide('markerProvide', markerProvide)
47+
48+
const mapProvide = inject<MapProvide>(MAP_PROVIDE);
49+
provide(MARK_PROVIDE, markerProvide);
50+
51+
const markerKey = getMarkerInjectKey(props.id);
52+
const mapKey = getMapInjectKey();
4453
4554
4655
nextTick(() => {
4756
fixImageUrl();
4857
const marker = L.marker(props.latlng, props.options);
49-
markerProvide.setMarker(marker);
50-
mapProvide?.getMap()?.addLayer(marker);
5158
59+
markerProvide.setMarker(markerKey, marker);
60+
61+
62+
mapProvide?.getMap(mapKey)?.addLayer(marker);
63+
64+
})
65+
66+
defineExpose({
67+
id: props.id,
68+
category: 'marker'
5269
})
5370
5471
function fixImageUrl() {

src/components/LPolygon.vue

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,27 +2,30 @@
22
import L, { PolylineOptions, LatLngExpression } from 'leaflet'
33
import { PropType, inject, nextTick } from 'vue';
44
import { MapProvide } from '../core/Map';
5+
import { MAP_PROVIDE, getMapInjectKey } from '../utils/injectKey';
56
6-
const mapProvide = inject<MapProvide>('mapProvide');
77
8+
const mapProvide = inject<MapProvide>(MAP_PROVIDE);
9+
10+
const key = getMapInjectKey();
811
912
const props = defineProps({
10-
latlng: {
13+
latlngs: {
1114
type: Object as PropType<LatLngExpression[] | LatLngExpression[][] | LatLngExpression[][][]>,
1215
required: true
1316
},
1417
options: {
15-
type: Object as PropType<PolylineOptions>,
16-
required: false
17-
}
18+
type: Object as PropType<PolylineOptions>,
19+
required: false
20+
}
1821
})
1922
2023
nextTick(() => {
21-
const polygon = L.polygon(props.latlng, props.options);
22-
mapProvide?.getMap()?.addLayer(polygon);
24+
const polygon = L.polygon(props.latlngs, props.options);
25+
26+
mapProvide?.getMap(key)?.addLayer(polygon);
2327
})
2428
2529
</script>
2630

27-
<template>
28-
</template>
31+
<template></template>

0 commit comments

Comments
 (0)