Advanced Usage
The basic components that vue3-google-map
provides are fully reactive and will get you pretty far. Should you need to access the Google Maps API, however, the GoogleMap
component exposes the following:
ready
: A boolean indicating when the Google Maps script has been loaded. By this point the map instance has been created, the API is ready for use and event listeners have been set up on the map.map
: The Map class instance.api
: The Google Maps API.mapTilesLoaded
: A boolean indicating when the map tiles have been fully loaded.
In addition, most of the subcomponents expose their instance should you need it:
Marker
exposesmarker
(a Marker class instance).Polyline
exposespolyline
(a Polyline class instance).Polygon
exposespolygon
(a Polygon class instance).Rectangle
exposesrectangle
(a Rectangle class instance).Circle
exposescircle
(a Circle class instance).InfoWindow
exposesinfoWindow
(an InfoWindow class instance).MarkerCluster
exposesmarkerCluster
(a MarkerClusterer class instance).HeatmapLayer
exposesheatmapLayer
(a HeatmapLayer class instance).
Usage Patterns
<script setup>
import { ref, computed, watch } from 'vue'
import { GoogleMap } from 'vue3-google-map'
const mapRef = ref(null)
// First pattern: compute some value using the API or map instance when "ready"
const markerIcon = computed(() => mapRef.value?.ready
? {
url: /* icon image url */,
scaledSize: new mapRef.value.api.Size(20, 20)
}
: null)
// Second pattern: watch for "ready" then do something with the API or map instance
watch(() => mapRef.value?.ready, (ready) => {
if (!ready) return
// do something with the api using `mapRef.value.api`
// or with the map instance using `mapRef.value.map`
})
</script>
<template>
<GoogleMap ref="mapRef">
<template #default="{ ready, api, map, mapTilesLoaded }">
<!-- Third pattern: Here you have access to the API and map instance.
"ready" is a boolean that indicates when the Google Maps script
has been loaded and the api and map instance are ready to be used -->
</template>
</GoogleMap>
</template>
Example:
<script setup>
import { ref, computed, watch } from 'vue'
import { GoogleMap } from 'vue3-google-map'
const mapRef = ref(null)
const center = { lat: 0, lng: 0 }
const _lng = ref(0)
const lng = computed({
get: () => _lng.value,
set: v => {
if (!Number.isFinite(v)) {
_lng.value = 0
} else if (v > 180) {
_lng.value = 180
} else if (v < -180) {
_lng.value = -180
} else {
_lng.value = v
}
},
})
watch([() => mapRef.value?.ready, lng], ([ready, lng]) => {
if (!ready)
return
mapRef.value.map.panTo({ lat: 0, lng })
})
</script>
<template>
<GoogleMap
ref="mapRef"
api-key="YOUR_GOOGLE_MAPS_API_KEY"
class="map"
:center="center"
:zoom="2"
/>
<label for="lng">Longitude</label>
<input v-model.number="lng" id="lng" type="number" min="-180" max="180" step="10" />
</template>
<style scoped>
.map {
position: relative;
width: 100%;
height: 500px;
}
.map::after {
position: absolute;
content: '';
width: 1px;
height: 100%;
top: 0;
left: 50%;
background: red;
}
label {
font-weight: 500;
}
input[type='number'] {
margin-top: 20px;
margin-left: 10px;
outline: 1px solid #ccc;
border-radius: 4px;
}
</style>
Loading the Google Maps API script externally
By default you would pass your API key as a prop to the GoogleMap
component and it handles the loading of the Google Maps API script for you. There are cases, however, where you might want to load the script yourself. For example, you might be using other Google Maps components or your Vue app might be a part of a larger app that uses the Google Maps API elsewhere. In these cases you can use the apiPromise
prop to pass a promise that resolves to the Google Maps API global google
object.
<script setup>
import { GoogleMap, Marker } from 'vue3-google-map';
import { Loader } from '@googlemaps/js-api-loader';
const loader = new Loader({
apiKey: '',
version: 'weekly',
libraries: ['places'],
});
const apiPromise = loader.load();
const center = { lat: 40.689247, lng: -74.044502 };
</script>
<template>
<GoogleMap
:api-promise="apiPromise"
style="width: 100%; height: 500px"
:center="center"
:zoom="15"
>
<Marker :options="{ position: center }" />
</GoogleMap>
</template>