Revisiting this 6 months later, I’ve made several significant changes and improvements in an actual plugin for Vue projects: x5-gmaps
This article is still great for learning and should be easier to follow along with, but please check out the source code and examples of the plugin too.
Recently I needed to use Google Maps for a project, and after a quick search, I found that the vast majority of recommendations were to just use the package vue2-google-maps. Now I did use it, and it’s great, but a) I prefer not to use packages, and b) I wanted to understand the Google Maps API first… So I made my own, and thought I’d share it.
Setup and Requirements
The Google Maps API
initMap() function and actual Google Maps API script. Looking at the API script link we can see that it needs our API key, and also has a callback to the
initMap() function. Looking at the
initMap() function we also see a simple logic of choosing a HTML element where the map object can be injected, and then creating a Google Maps Marker which we feed a geolocation and the defined map object.
Easy. Let’s do that all in Vue.
OK, so creating a new Vue project using the CLI
vue create vue-maps-example we are going to need to include this Google Maps API script somewhere. For simplicity, just put it in the same position as in the example, in your
[public]/index.html, and let’s also get rid of the callback variable:
Now, let’s keep it simple and replace the
App.vue. For our template, we just need to add a map div inside the app div:
And some quick styling:
And then for the script we can basically copy the tutorial with some minor changes:
1. We are storing our created Map object in the Vue data property
map for our later use.
2. To access the injected global variable Google Maps in Vue, we need to add
window in front of the reference (
3. To get the element to inject into, we are using refs which is one of MANY ways to access the DOM.
Now we can give it the element Vue reference (
map), and the options for the map in an object (see all the options here) et voila.
So you should have a map showing now like in the tutorial (minus the marker).
Now to add the marker, you can use almost exactly the same code in the tutorial but with aforementioned differences:
But that’s not a reusable component! OK so instead let’s get our Map ready for some components. So that we can use things like v-for loops, we want to end up with this working:
As we’ve seen, we can easily add things to the map *if* we have the map reference; but the devil is in the details. You see, after the HTML of the page loads, it runs the JS scripts (Vue.js and Google Maps API script), and then sends off a check to make sure your API key is good, and if it is then the Google Maps API script will do your bidding. BUT! That all takes time, so if you don’t consider that, you will continually run into errors as Vue will load it, and it will throw an error because it can’t find the map… I am embarrassed to tell you how long this took me to figure out.
So, we’re going to make a map method that the map’s children can access that will run a callback AFTER the map is loaded:
OK, so let’s make a new component:
Now a Marker does not have custom HTML, and it’s all handled by Google Maps, so we don’t need a template or style. All we need is a script:
1. Two properties which must be included and must be numbers
2. A data property to track the created marker
3. The marker creation code in the
4. Disposal code in the
5. A render function because we don’t have a template
And then, if all went well, if you add in some MapMarker components (like we said we wanted at the top) as children of the Map, you should see the markers showing up.
You can see code here if you got lost.
Bonus: Info Window
Very similarly, we can add Info Windows in the same way, but they’re a little more interesting as you can put HTML inside them… So we already have our parent Map setup so can jump straight into the
MapInfoWindow.vue component. This one does have a template but it’s just a div to hold a slot:
And the script:
1. Basically the same as the Marker
2. An additional option of
content which is the HTML element that should be put into the window. I used
this.$el which means the component root element (the
3. While not needed, the 3rd parameter stops the map from panning to the created Info Window. This may be desired, but when I added 20 of them the window jumped around and looked terrible.
4. We need to
close() Info Windows (the little x in the bubble created also closes it)
Now for our map:
That’s all for now. Google Maps Popups are a bit harder and will need their own tutorial. Let me know if you want to see that too.