fix(map): convert Google Maps object arrays to shallowRef to prevent deep reactivity proxies from breaking setMap(null) and causing memory leaks/ghost markers

This commit is contained in:
2026-03-04 12:32:37 -05:00
parent 9c7050436b
commit af8ddd34a6

View File

@ -1,9 +1,12 @@
import { ref } from 'vue'
import { ref, shallowRef, triggerRef } from 'vue'
const markers = ref<google.maps.Marker[]>([])
const polylines = ref<google.maps.Polyline[]>([])
const infoWindows = ref<google.maps.InfoWindow[]>([])
const circles = ref<google.maps.Circle[]>([])
// PERFORMANCE FIX: Los objetos de Google Maps NUNCA deben ir en refs profundos (ref)
// porque Vue intenta proxyficarlos ("deep reactivity") y rompe sus métodos internos
// provocando un fallo silencioso en setMap(null). Usamos shallowRef.
const markers = shallowRef<google.maps.Marker[]>([])
const polylines = shallowRef<google.maps.Polyline[]>([])
const infoWindows = shallowRef<google.maps.InfoWindow[]>([])
const circles = shallowRef<google.maps.Circle[]>([])
// Callback para sincronización externa (ej. useGoogleMaps globalOverlays)
const onLimpiarCallback = ref<(() => void) | null>(null)
@ -11,25 +14,37 @@ const onLimpiarCallback = ref<(() => void) | null>(null)
export const useMapState = () => {
const registrarMarker = (marker: any) => {
if (marker) markers.value.push(marker as google.maps.Marker)
if (marker) {
markers.value.push(marker as google.maps.Marker)
triggerRef(markers)
}
return marker
}
// Registrar una polyline
const registrarPolyline = (polyline: google.maps.Polyline) => {
if (polyline) polylines.value.push(polyline)
if (polyline) {
polylines.value.push(polyline)
triggerRef(polylines)
}
return polyline
}
// Registrar un circle
const registrarCircle = (circle: google.maps.Circle) => {
if (circle) circles.value.push(circle)
if (circle) {
circles.value.push(circle)
triggerRef(circles)
}
return circle
}
// Registrar un InfoWindow
const registrarInfoWindow = (infoWindow: google.maps.InfoWindow) => {
if (infoWindow) infoWindows.value.push(infoWindow)
if (infoWindow) {
infoWindows.value.push(infoWindow)
triggerRef(infoWindows)
}
return infoWindow
}