Using Google Maps in Vue with vue-google-maps

Phil Miller

Google Maps presents a robust set of APIs for building and interacting with maps, visualizing location data, and searching via autocomplete, to name but a few. While the sheer breadth of their offering seems a bit overwhelming, it’s actually quite simple to get started.

We’ll use the fork of vue-google-maps which has been updated for Vue 2. It comes with a well-rounded set of components for interacting with Google Maps as well as two-way data binding.

Installation

If you want to skip installation and get started right away, here's a codesandbox with everything you need, just add your API key.

If starting from scratch, use the vue-cli template of your choice (we like webpack-simple). Then install vue2-google-maps, note this is the updated version for Vue 2.

$ npm install vue2-google-maps --save

Get API Key

There’s a handy button right in the Maps Javascript API docs. Simply click on ‘GET A KEY’ and follow the instructions. Also, if you plan on releasing anything into the wild, it’s best to add your billing information as this will drastically raise your ‘free’ daily API limits.

Add to Vue with vue2-google-maps

Import vue2-google-maps in main.js and instantiate the plugin using your API key from above. Note that we are also telling it to load the places library, which is required for the autocomplete.

main.js

import Vue from "vue";
import App from "./App";
import * as VueGoogleMaps from "vue2-google-maps";

Vue.use(VueGoogleMaps, {
  load: {
    key: "REPLACE-THIS-WITH-YOUR-KEY-FROM-ABOVE",
    libraries: "places" // necessary for places input
  }
});

new Vue({
  el: "#app",
  components: { App },
  template: "<App/>"
});

Map Search Component

Create a new component called GoogleMap.vue and paste the following into it:

components/GoogleMap.vue

<template>
  <div>
    <div>
      <h2>Search and add a pin</h2>
      <label>
        <gmap-autocomplete
          @place_changed="setPlace">
        </gmap-autocomplete>
        <button @click="addMarker">Add</button>
      </label>
      <br/>

    </div>
    <br>
    <gmap-map
      :center="center"
      :zoom="12"
      style="width:100%;  height: 400px;"
    >
      <gmap-marker
        :key="index"
        v-for="(m, index) in markers"
        :position="m.position"
        @click="center=m.position"
      ></gmap-marker>
    </gmap-map>
  </div>
</template>

<script>
export default {
  name: "GoogleMap",
  data() {
    return {
      // default to Montreal to keep it simple
      // change this to whatever makes sense
      center: { lat: 45.508, lng: -73.587 },
      markers: [],
      places: [],
      currentPlace: null
    };
  },

  mounted() {
    this.geolocate();
  },

  methods: {
    // receives a place object via the autocomplete component
    setPlace(place) {
      this.currentPlace = place;
    },
    addMarker() {
      if (this.currentPlace) {
        const marker = {
          lat: this.currentPlace.geometry.location.lat(),
          lng: this.currentPlace.geometry.location.lng()
        };
        this.markers.push({ position: marker });
        this.places.push(this.currentPlace);
        this.center = marker;
        this.currentPlace = null;
      }
    },
    geolocate: function() {
      navigator.geolocation.getCurrentPosition(position => {
        this.center = {
          lat: position.coords.latitude,
          lng: position.coords.longitude
        };
      });
    }
  }
};
</script>

Let’s break down what’s happening here.

We’re creating a gmap-autocomplete and a gmap-map (with children gmap-markers). Initially, the map is created centered on Montreal. After the instance is mounted(), we call geolocate and re-center.

Once a user enters a search term and makes a selection from the autocomplete dropdown, the gmap-autocomplete calls setPlace. This selection is then stored in currentPlace. When the add button is clicked, we call addPlace which stores the marker location in markers, triggering the gmap-map (and subsequently gmap-markers) to update. We’re also updating center to the position of the last marker. Additionally, we’re storing each place’s full place object in the places property. This will allow any additional data returned from the automplete query to be used in this component or any child components, as needed.

Add to App.vue

Lastly, just add your new component in App.vue and everything should look something like this:

App.vue

<template>
  <div id="app">
    <google-map />
  </div>
</template>

<script>
import GoogleMap from "./components/GoogleMap";

export default {
  name: "App",
  components: {
    GoogleMap
  }
};
</script>

And the “app” should look like this (if you were in Iceland):

google maps autocomplete search

👉 That's it! The 🌍 is yours :)

  Tweet It

🕵 Search Results

🔎 Searching...