[v2.1, Code updated June 2021]
Why on earth everyone is using plugins just to add Map script and to call its APIs/methods! VueJS is Javascript, Map APIs available in Javascript, yet... can't you just use it?!
The only important thing is - for Vue CLI project, the time when you use the google.maps
object, transpiler will show an error; you have to add the window scope explicitly like new window.google.maps...()
.
Let's dive into the detail. We will use a function to attach the Map script programmatically (you can add the Map <script>
tag directly in html, but that have caveat; check footnote). If you need Map APIs on multiple views then make this function/method global by placing it in vue.mixin
or index.html
etc. Otherwise you can use it in your desired component making it a method. Here I'm going to use it as a global function:
// Add google map script if not exist; if already exist, return true
window.checkAndAttachMapScript = function (callback) {
let scriptId = "map-api-script";
let mapAlreadyAttached = !!document.getElementById(scriptId);
if (mapAlreadyAttached) {
if (window.google) // Script attached but may not finished loading; so check for 'google' object.
callback();
}
else {
window.mapApiInitialized = callback;
let script = document.createElement('script');
script.id = scriptId;
script.src = 'https://maps.googleapis.com/maps/api/js?key=_YOUR_KEY_HERE_&libraries=places,geometry&callback=mapApiInitialized';
document.body.appendChild(script);
}
return mapAlreadyAttached;
}
Now in your callback
, do whatever you wanted to do with Map. Here I will initialize Place Autocomplete:
<!-- Vue single-file component -->
<template>
<div>
<input
type="text"
ref="search"
v-model="location"
/>
</div>
</template>
<script>
export default {
data: () => ({
location: null
}),
mounted() {
window.checkAndAttachMapScript(this.initLocationSearch);
},
methods: {
initLocationSearch() {
let autocomplete = new window.google.maps.places.Autocomplete(this.$refs.search);
autocomplete.addListener("place_changed", function() {
let place = autocomplete.getPlace();
if (place && place.address_components) {
console.log(place.address_components);
}
});
}
}
};
</script>
The End
Footnote
Attaching script programmatically will have more control. If a visitor directly landed on a page of your application where Map API is not need, then the script will not be loaded. If you add it directly in index.html, it will be loaded whether used or not. Eventually unnecessarily consumes bandwidth and CPU+battery on mobile devices.
Reference:
- List of libraries for
libraries=
querystring: https://developers.google.com/maps/documentation/javascript/libraries
Top comments (4)
This is really helpful when I first trying to add google map to my current project,
but then I had to call map object from another component for street view, I can't pull it out :<
first I try to move
window.checkAndAttachMapScript = function (callback)
to root component, and have different callback function in different components, but got 'google is not define' error or
'You have included the Google Maps API multiple times on this page' error
can I bother you with a complete demo for a google map object using cross multiple components?
Sorry, im late for 25 days ~facepalm~; haven't been checking dev.to for a while. Anyways.. did you solve it?
For now, I can point following things out-
callback
itself is a function, which is getting passed to another function. So not sure whether you made a typo here or you know exactly what you are doing!This is the reason I wrote this post. If you write
new google.maps.StreetViewPanorama(...)
, you will get "google is not defined" error. You have to write: new window.google.maps.StreetViewPanorama(...).Probably every time you are calling
checkAndAttachGoogleMap
method, you are adding another <script> tag. So you need to review your code.Dude this helped me so much thank you!
Hahaha... maybe you're talking about my first para.
Some comments have been hidden by the post's author - find out more