Skip to content

Commit ab1d5e8

Browse files
authored
fix(google-maps): avoid recentering google maps on inline options (#740)
1 parent ada747d commit ab1d5e8

2 files changed

Lines changed: 50 additions & 3 deletions

File tree

packages/script/src/runtime/components/GoogleMaps/ScriptGoogleMaps.vue

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -259,6 +259,21 @@ function isLocationQuery(s: string | any) {
259259
return typeof s === 'string' && (s.split(',').length > 2 || s.includes('+'))
260260
}
261261
262+
type ScriptGoogleMapsCenter = ScriptGoogleMapsProps['center'] | google.maps.MapOptions['center']
263+
264+
function getCenterWatchKey(center: ScriptGoogleMapsCenter): string | undefined {
265+
const raw = toRaw(center)
266+
if (!raw)
267+
return undefined
268+
if (typeof raw === 'string')
269+
return `query:${raw}`
270+
const lat = typeof (raw as any).lat === 'function' ? (raw as any).lat() : (raw as any).lat
271+
const lng = typeof (raw as any).lng === 'function' ? (raw as any).lng() : (raw as any).lng
272+
if (lat != null && lng != null)
273+
return `latlng:${lat},${lng}`
274+
return undefined
275+
}
276+
262277
const queryToLatLngCache = new Map<string, google.maps.LatLng | google.maps.LatLngLiteral>()
263278
264279
async function resolveQueryToLatLng(query: string) {
@@ -449,14 +464,14 @@ onMounted(() => {
449464
// Clear centerOverride when the controlled center prop changes so external
450465
// updates take effect (otherwise centerOverride, written from the user's
451466
// pan during re-init, would permanently win over future prop updates).
452-
watch([() => props.center, () => props.mapOptions?.center], () => {
467+
watch([() => getCenterWatchKey(props.center), () => getCenterWatchKey(props.mapOptions?.center)], () => {
453468
centerOverride.value = undefined
454469
})
455-
watch([() => options.value.center, isMapReady, map], async (next) => {
470+
watch([() => getCenterWatchKey(options.value.center), isMapReady, map], async () => {
456471
if (!map.value) {
457472
return
458473
}
459-
let center = toRaw(next[0])
474+
let center = toRaw(options.value.center)
460475
if (center) {
461476
if (isLocationQuery(center) && isMapReady.value) {
462477
center = await resolveQueryToLatLng(center as string)

test/unit/google-maps-regressions.test.ts

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -455,6 +455,38 @@ describe('google Maps Regressions', () => {
455455

456456
expect(map.setCenter).not.toHaveBeenCalled()
457457
})
458+
459+
it('uses a stable center watch key for equivalent inline mapOptions centers', () => {
460+
function getCenterWatchKey(center: any) {
461+
if (!center)
462+
return undefined
463+
if (typeof center === 'string')
464+
return `query:${center}`
465+
const lat = typeof center.lat === 'function' ? center.lat() : center.lat
466+
const lng = typeof center.lng === 'function' ? center.lng() : center.lng
467+
if (lat != null && lng != null)
468+
return `latlng:${lat},${lng}`
469+
return center
470+
}
471+
472+
const firstRender = { center: { lat: -34.397, lng: 150.644 }, zoom: 8 }
473+
const secondRender = { center: { lat: -34.397, lng: 150.644 }, zoom: 8 }
474+
475+
expect(firstRender.center).not.toBe(secondRender.center)
476+
expect(getCenterWatchKey(firstRender.center)).toBe(getCenterWatchKey(secondRender.center))
477+
})
478+
479+
it('changes the center watch key when coordinates actually change', () => {
480+
function getCenterWatchKey(center: any) {
481+
const lat = typeof center.lat === 'function' ? center.lat() : center.lat
482+
const lng = typeof center.lng === 'function' ? center.lng() : center.lng
483+
return `latlng:${lat},${lng}`
484+
}
485+
486+
expect(getCenterWatchKey({ lat: -34.397, lng: 150.644 }))
487+
.not
488+
.toBe(getCenterWatchKey({ lat: -34.387, lng: 150.654 }))
489+
})
458490
})
459491

460492
describe('infoWindow group close', () => {

0 commit comments

Comments
 (0)