1/** 2 * Vue 3 Leaflet MarkerCluster component 3 * A lightweight wrapper around Leaflet.markercluster 4 */ 5export default { 6 props: { 7 options: { 8 type: Object, 9 default() { 10 return {} 11 }, 12 }, 13 }, 14 emits: ['ready'], 15 data() { 16 return { 17 ready: false, 18 mapObject: null, 19 parentContainer: null, 20 } 21 }, 22 mounted() { 23 this.mapObject = new L.MarkerClusterGroup({ 24 ...this.options, 25 showCoverageOnHover: false, 26 animate: true, 27 spiderfyOnMaxZoom: true, 28 spiderfyMaxCount: Infinity, 29 spiderfyDistanceMultiplier: 1.1, 30 chunkedLoading: true, 31 iconCreateFunction(cluster) { 32 const childCount = cluster.getChildCount() 33 const size = 34 childCount < 10 ? 'small' : childCount < 100 ? 'medium' : 'large' 35 return new L.DivIcon({ 36 html: `<div><span>${childCount}</span></div>`, 37 className: `marker-cluster ${size}`, 38 iconSize: new L.Point(40, 40), 39 }) 40 }, 41 maxClusterRadius: (zoom) => { 42 if (zoom > 10) return 60 43 if (zoom > 7) return 70 44 return 70 45 }, 46 }) 47 48 // Extract event listeners from $attrs (Vue 3 pattern) 49 const eventListeners = {} 50 Object.keys(this.$attrs).forEach((key) => { 51 if (key.startsWith('on') && typeof this.$attrs[key] === 'function') { 52 const eventName = key.slice(2).toLowerCase() 53 eventListeners[eventName] = this.$attrs[key] 54 } 55 }) 56 L.DomEvent.on(this.mapObject, eventListeners) 57 58 // Find parent map component 59 let parent = this.$parent 60 while (parent && !parent.mapObject) { 61 parent = parent.$parent 62 } 63 this.parentContainer = parent 64 65 // Add to parent map 66 if (this.parentContainer && this.parentContainer.mapObject) { 67 this.parentContainer.mapObject.addLayer(this.mapObject) 68 } 69 70 this.ready = true 71 this.$nextTick(() => { 72 this.$emit('ready', this.mapObject) 73 }) 74 }, 75 beforeUnmount() { 76 if (this.parentContainer && this.parentContainer.mapObject) { 77 this.parentContainer.mapObject.removeLayer(this.mapObject) 78 } 79 }, 80 methods: { 81 addLayers(layers) { 82 if (!layers) return 83 this.mapObject.clearLayers() 84 this.mapObject.addLayers(layers) 85 }, 86 clearLayers() { 87 if (this.mapObject) { 88 this.mapObject.clearLayers() 89 } 90 }, 91 refreshClusters() { 92 if (this.mapObject) { 93 this.mapObject.refreshClusters() 94 } 95 }, 96 }, 97 template: ` 98 <div style="display: none;"> 99 <slot v-if="ready"></slot> 100 </div> 101 `, 102}
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.