Most of the properties and events here are not documented unless they do not exist in the original Google Maps API. Otherwise they behave similarly to a direct call to the API so you are advised to read that instead.
An exception is two-way bindings -- the center_changed
event on Map instances
have no argument, but in vue2-google-maps they do in order to ease two-way updates.
- vue2-google-maps
- Table of Contents
- Getting Started (with Nuxt.js)
- Getting Started (with CDN)
- Getting Started (with NPM)
- Classes
- install(Vue: Vue, options: InstallOptions) : void
- loaded() : Promise
- Map class (mixes in
DeferredReadyMixin
) - StreetViewPanorama class (mixes in
DeferredReadyMixin
) - Marker class (mixes in
MapElementMixin
) - Cluster class (mixes in
MapElementMixin
) - Cluster class (mixes in
MapElementMixin
) - InfoWindow class (mixes in
MapElementMixin
) - Polyline class (mixes in
MapElementMixin
) * $polylineObject : google.maps.Polyline - Polygon class (mixes in
MapElementMixin
) - Circle class (mixes in
MapElementMixin
) - Rectangle class (mixes in
MapElementMixin
) - Autocomplete class (mixes in
MapElementMixin
) - PlaceInput class (mixes in
MapElementMixin
) (deprecated) - DeferredReadyMixin
- MapElementMixin (mixes in
DeferredReadyMixin
) - MountableMixin
Created by gh-md-toc
- Create a plugin:
plugins/maps.js
import Vue from 'vue'
import * as VueGoogleMaps from '~/node_modules/vue2-google-maps/src/main'
Vue.use(VueGoogleMaps, {
load: {
key: 'YOUR_API_KEY',
v: 'GOOGLE_MAPS_VERSION',
libraries: 'places' // Only if you need Autocomplete
}
})
The reason you need ~/node_modules
is found here.
This can be summarized as, when rendering server-side, (1) if the require()
-ed object is part of a
module (e.g. require('vue2-google-maps')
), load it as a Javascript module.
(2) Otherwise (e.g. require('./node_modules/vue2-google-maps')
) evaluate it as a webpack module.
Because .vue files are syntactically invalid Javascript, they will break your server-side loader
if they are loaded as a Javascript module. However they work fine if we can somehow instruct
Webpack to compile it. Hence, we do (2).
- Include your plugin in
nuxt.config.js
:
nuxt.config.js
{
plugins: [
'~plugins/maps.js'
]
}
TODO (this package has not yet been published to a CDN).
Install your package via NPM:
$ npm install vue2-google-maps
Import the components you need:
const VueGoogleMaps = require('vue2-google-maps');
Vue.use(VueGoogleMaps, {
load: {
key: 'YOUR_API_KEY',
v: 'GOOGLE_MAPS_VERSION',
libraries: 'places'
}
})
// The following components are automatically installed globally
// If you would like to define your own component names,
// see below
// GmapMap
// GmapMarker
// GmapCluster
// GmapInfoWindow
// GmapPolyline
// GmapPolygon
// GmapCircle
// GmapRectangle
// GmapPlaceInput
Write your Vue component
<style>
.map-container {
width: 500px;
height: 300px;
}
</style>
<div id="app">
<div class="map-container">
<gmap-map :center="{lat:1.38, lng:103.8}" :zoom="12">
<gmap-marker :position="{lat:1.38, lng:103.8}">
</gmap-marker>
<gmap-info-window :position="{lat:1.38, lng:103.8}">
Hello world!
</gmap-info-window>
</gmap-map>
</div>
</div>
<script>
new Vue({
el: '#app'
})
</script>
Use the options
property in gmap-map
compontent to add styles and options (see Google Maps API for details on this).
<template>
<gmap-map :options="{styles: styles}" ></gmap-map>
</template>
<script>
export default {
data () {
return {
styles: [ // styles here ]
}
}
}
</script>
Properties described here have a corresponding
property_changed
event if they are marked with †.
They correspond to two-way properties in vue-google-maps
, but allows you
two work around the lack of two-way bindings in Vue 2.
interface InstallOptions {
installComponents?: boolean = true,
load?: LoadOptions
}
interface LoadOptions {
key: string,
v: string,
libraries: string,
[key: string]: string
}
Installs VueGoogleMaps on an instance of Vue.
Automatically installs the available components
as Gmap*
. If you would like to give the components your
own names, set this to false, then install the components manually,
e.g. Vue.component('google-maps-circle', VueGoogleMaps.Circle)
.
Sets the API key etc. for the Google Maps JS API. You may set additional options, e.g. for Google Maps Premium. These will be passed as the query string to the Google Maps JS Library.
Promise resolved once the Google Maps API is loaded.
deferredReady
is called once mapObject
has been initialized.
The Google Maps instance. Example usage:
google.maps.event.trigger(this.$refs.map.$mapObject, 'resize')
Promise resolved when the map has been created
Methods can be executed on a map using the ref
attribute supplied to your gmap-map
element. For example, if you have an element of <gmap-map ref="example" ... > </gmap-map>
, you can pan this map by doing:
this.$refs.example.panBy(10,10)
A shorthand for:
google.maps.event.trigger(mapComponent.$mapObject, 'resize')
The same as resize()
, but keeps the center of the map.
Warning: Do not do the following if you need two-way binding:
<gmap-map :center="center" @center_changed="updateCenter"></gmap-map>
methods: {
updateCenter(center) {
this.center = {
lat: center.lat(),
lng: center.lng()
}
}
}
The center reported by center_changed
is not guaranteed to be the same
as the center you give to the maps. As a result, you are going to get an endless
loop:
this.center = {...} --> center_changed --> this.center = {...} --> center_changed --> ...
Instead, if you need two-way binding, save the center from center_changed
in a separate property, and synchronize it with the map center only when you
really need to. Refer to app.vue in the examples.
Can we get the old behaviour back? No. vue-google-maps
v0.1.x was able
to prevent the infinite loop
because it handled two-way binding on its own, and therefore can set up the
event listeners to break the endless loop before it happens.
In vue2-google-maps
the events are provided by the parent component.
The Map component is not able to tell which of the event listeners are listening
for all events, and which event listeners are listening only for UI-initiated
events for the purpose of two-way binding
(or maybe it could, with some extra attributes. Submit a PR ^.^). Therefore
the responsibility of breaking the infinite loop now lies with you, the user.
HTML elements in the default slot are invisible. This is because some elements require auxiliary HTML elements, and keeping the default slot invisible should (I haven't tested it) improve rendering speeds.
The map container has CSS position relative
by default.
This allows you to overlay regular HTML elements over
the map by placing them
in the visible
slot.
For example, you can place position-selection crosshairs
in the centre of the map
(used in mobile apps like Uber) by specifying
{left: 50%, top: 50%, position: absolute}
; you can
add a status bar to show information when hovering over
markers such as in the Info Bar example.
This class is experimental. (Note from author: I don't have a use case for it yet, so I can't dogfood this implementation.)
Promise resolved when the map has been created
The first Cluster
instance (going up the hierarchy chain)
among this component's ancestors.
This marker will be clustered by this clusterer.
The clusterer this marker is part of, or null
if
the marker is not part of a clusterer.
Set in deferredReady
.
To use this class in standalone mode, you need to include the following:
<script src="https://cdn.rawgit.com/mahnunchik/markerclustererplus/2.1.4/dist/markerclusterer.min.js"></script>
To use this class with NPM, you need to npm install marker-clusterer-plus
.
Place Marker
objects within <gmap-cluster></gmap-cluster>
in order to use marker clustering.
Example:
<gmap-info-window>Hello world!</gmap-info-window>
Whether to perform a deep watch on the path
property.
Set to false
to improve performance.
Whether to perform a deep watch on the path
property.
Set to false
to improve performance.
The root element of this class is an INPUT
element.
Therefore it is possible to set the class
, value
, v-model
etc. and other
attributes on the element.
Simulates a 'down arrow' keypress on hitting 'return' when no pac suggestion is selected, and then triggers the original listener.
Sets the class on the <input>
element, but we call it
className
because class
is disallowed by Vue 2.
Simulates a 'down arrow' keypress on hitting 'return' when no pac suggestion is selected, and then triggers the original listener.
Actions to be performed before deferredReady()
is called.
These is executed after all ancestor components' deferredReady()
have
been called.
A hook that waits for ancestors' deferredReady()
to complete (i.e. Promise resolved)
before it is itself called.
This Mixin is used in this package in order to initialize the Map component only after the Maps API has been loaded, and to initialize map elements only after the ancestor Map component has been initialized.
This mixin adds a beforeDeferredReady()
hook which initializes this.$map
.
A reference to the ancestor Map component. This is available only after
deferredReady()
has been called. You can access the map by:
this.$map.$mapObject
.
Props: resizeBus : Vue
(Default: Vue.$gmapDefaultResizeBus
)
Methods: _resizeCallback()
Use this mixin to implement top-level components which mounts over an existing element (e.g. maps, street view panoramas).
This mixin is intended to help manage the resize()
calls.
Google Maps components need to know the size of the
element they are mounted on. If you have reactive styles and
classes (for example when you use vue-router
) you need to
call resize()
on every component used by the Maps API
whenever there are changes to the visibility / size of the
mounted element.
By using this mixin, components will listen on the bus
(an object with $on
, $off
and $emit
such as Vue
)
for the resize
event, whereupon it will trigger a resize.
If a resizeBus
is not specified, it will listen on the
default global bus, Vue.$gmapDefaultResizeBus
.
If you are creating new components, override _resizeCallback
to define the desired behaviour when the resize is triggered.
For example, in a GmapMap
, _resizeCallback
calls vm.resizePreserveCenter()
.
By default it will delay the resize by one tick. If you need longer ticks in order for styles to be fully applied, try delaying emitting the trigger.