JSPM

  • Created
  • Published
  • Downloads 1008
  • Score
    100M100P100Q102907F
  • License MIT

A lightweight Google Maps plugin for Vue

Package Exports

  • x5-gmaps

This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (x5-gmaps) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.

Readme

x5-gmaps (Live Demo)

npm bundle size

This is a lightweight Google Maps plugin for Vue 2 Now with Typescript! 🥳

Samples/examples/tutorials

  • These use slightly older versions of this package but are similar enough for you to get the idea. Read below for the latest on how to use each component.

Installation

# npm
npm install x5-gmaps

Deployment

This plugin can be installed like any Vue plugin:

import x5GMaps from 'x5-gmaps';
// Option 1: Just your key
Vue.use(x5GMaps, 'YOUR_GOOGLE_KEY');
// Option 2: With libraries
Vue.use(x5GMaps, { key: 'YOUR_GOOGLE_KEY', libraries: ['places'] });

new Vue({
  el: '#app',
  render: h => h(App)
});

If you're using Typescript, you will need to add the Types into your tsconfig.json file as you would any other library.

{
  "compilerOptions": {
    "types": [
      "x5-gmaps"
    ]
  }
}

For Quasar, because you cannot use Vue.use(), in a boot file you can import the default export as 'install' and run that with the Vue instance and options as the parameters:

import { install } from 'x5-gmaps';

export default async ({ Vue }) => {
  install(Vue, 'XXXXXX');
  // install(Vue, { key: "XXXXXX", libraries: ["places"] });
};

⚠️ This plugin is not transpiled! If you want it compatible with IE, Edge, and Safari, you need to add this to your vue.config.js file:

module.exports = {
  transpileDependencies: ['x5-gmaps']
};

Usage

<template>
  <gmaps-map>
    <gmaps-marker :position="{ lat: -27, lng: 153 }" />
  </gmaps-map>
</template>
import { gmapsMap, gmapsMarker } from 'x5-gmaps';

export default {
  components: { gmapsMap, gmapsMarker }
};

Provided Components

Some pre-built components have been provided for general use, or as examples for those who wish to take them further.

Map

Map

Maps can take many options. zoom is defaulted to 12 and center is defaulted to Brisbane (as these options are required). The type of these is google.maps.MapOptions.

This component supports the following events:

  • @bounds-changed returns new bounds
  • @center-changed returns new center
  • @zoom-changed returns new zoom level
  • @click returns event
  • @double-click returns event
  • @right-click returns event
  • @mouseover returns event
  • @mouseout returns event

Once the map is loaded, it $emit's itself (map instance) via the event mounted (thanks thefoxie).

The default template for the slot also has a slot prop of map which can be referred to.

<template>
  <gmaps-map :options="mapOptions" />
</template>

<script>
  import { gmapsMap } from 'x5-gmaps';

  export default {
    components: { gmapsMap },
    data: () => ({
      mapOptions: {
        center: { lat: -27.47, lng: 153.025 },
        zoom: 12
      }
    })
  };
</script>

Marker

Marker

Markers are placed within Maps and can take many options. A position option is required within the options prop or as its own prop.

This component supports the following events:

  • @move returns new position { lat, lng }
  • @click returns event
  • @double-click returns event
  • @right-click returns event
  • @positionChanged (depreciated) returns new position
Props Type Default Description
options* Object - Type: google.maps.MarkerOptions
icon String / Object - Marker icon URL / Icon Interface
label String / Object - Marker label text / Label Interface
opacity Number 1.0 Opacity of the marker
position Object - { lat: number, lng: number } (Type: google.maps.LatLngLiteral)
sensitivity Number 0.001 Changes movement sensitivity to save processing when there are a lot of items on the map
title String - Marker title (shown on hover)
visible Boolean true If marker is visible
zIndex Number - Override position in DOM

* If you want to change values on the fly, use the named props instead of within the options prop. Changing named props will trigger an update.

<template>
  <gmaps-map>
    <gmaps-marker v-for="(item, i) in items" :key="i" :options="item.options" />
  </gmaps-map>
</template>

<script>
  import { gmapsMap, gmapsMarker } from 'x5-gmaps'

  export default {
    components: { gmapsMap, gmapsMarker },
    data: () => ({
      items: [
        { options: { position: { lat: -27.41, lng: 153.01 } } },
        { options: { position: { lat: -27.42, lng: 153.02 } } },
        ...,
        { options: { position: { lat: -27.48, lng: 153.08 } } },
        { options: { position: { lat: -27.49, lng: 153.09 } } },
      ],
    }),
  }
</script>

InfoWindow

InfoWindow

InfoWindows are placed with Maps can take a few options using the type google.maps.InfoWindowOptions. A position option { lat: number, lng: number } (Type: google.maps.LatLngLiteral) is required.

They are used to put HTML in and have a close/dismiss button built-in.

This component only supports a @closed event (for when someone closes the window)

<template>
  <gmaps-map :options="mapOptions">
    <gmaps-info-window :options="options">
      <p>Example Text</p>
    </gmaps-info-window>
  </gmaps-map>
</template>

<script>
  import { gmapsMap, gmapsInfoWindow } from 'x5-gmaps';

  export default {
    components: { gmapsMap, gmapsInfoWindow },
    data: () => ({
      options: {
        position: { lat: -27.46, lng: 153.02 }
      },
      mapOptions: {
        center: { lat: -27.47, lng: 153.025 },
        zoom: 12
      }
    })
  };
</script>

Popup

A Popup is a custom DOM Element. It is here primarily as an example of what is needed when creating your own map objects, but serves as a cleaner InfoWindow for Vue.

It takes the following props:

Props Type Default Description
position Object - { lat: number, lng: number } (Type: google.maps.LatLngLiteral)
background String #EEEEEE Background style
height String 200px Height style
width String 60px Width style

All events are registered from the markup/component you place inside it rather than the popup itself.

<template>
  <gmaps-map :options="mapOptions">
    <gmaps-popup :position="position" background="#BBF0FF">
      <span @click="doSomething()">Do Something</span>
    </gmaps-popup>
  </gmaps-map>
</template>

<script>
  import { gmapsMap, gmapsPopup } from 'x5-gmaps';

  export default {
    components: { gmapsMap, gmapsPopup },
    data: () => ({
      position: { lat: -27.46, lng: 153.02 },
      mapOptions: {
        center: { lat: -27.47, lng: 153.025 },
        zoom: 12
      }
    })
  };
</script>

Heatmap

Heatmap

Heatmaps are placed within Maps and have several props which are derived from Google's Heatmap Options. Some are named differently as they have been enhanced/simplified.

Props Type Default Description
items Array/Object required An array of { lat: number, lng: number } (Type: google.maps.LatLngLiteral)
colors Array/String - An array of one or more colors to color heatmap e.g. ['red','#0F0','rgba(0,0,0,0)`]
dissipating Boolean true Specifies whether heatmaps dissipate on zoom
opacity Number 0.6 Opacity of the heatmap
maxIntensity Number - Number of points in one spot to reach "maximum heat" color
radius Number - The radius of influence for each data point, in pixels
weightProp String - The property of items that should be used as the weight (Numbers > 0)

This component does not have any events.

** Note require to include the "visualization" library as described in Deployment

<template>
  <gmaps-map>
    <gmaps-heatmap :data="items" :opacity="0.8" />
  </gmaps-map>
</template>

<script>
  import { gmapsMap, gmapsHeatmap } from 'x5-gmaps'

  export default {
    components: { gmapsMap, gmapsHeatmap },
    data: () => ({
      items: [
        { lat: -27.41, lng: 153.01 },
        { lat: -27.42, lng: 153.02 },
        ...,
        { lat: -27.48, lng: 153.08 },
        { lat: -27.49, lng: 153.09 },
      ],
    }),
  }
</script>

Polylines / Polygons

Polyline Polygon

Polylines/polygons are placed within Maps and have several props which are derived from Google's Polyline Options and Polygon Options.

This component supports the following events:

Props Type Default Description
clickable Boolean true Indicates whether this Polyline handles mouse events
draggable Boolean false Allow the shape to be dragged over the map
editable Boolean false Allow editing the shape by dragging the control points
fillColor String black (Only polygons) The fill color ***
fillOpacity Number 0.3 (Only polygons) The fill opacity between 0.0 and 1.0
geodesic Boolean false When true, lines will follow the curvature of the Earth
icons Array [] (Only polylines) Add icons along your path **
path Array required Array of { lat: number, lng: number } (Type: google.maps.LatLngLiteral)
strokeColor String black The stroke color ***
strokePosition Number 0 (Only polygons) The stroke position along the path (0 = CENTER / 1 = INSIDE / 2 = OUTSIDE)
strokeOpacity Number 1.0 The stroke opacity between 0.0 and 1.0
strokeWeight Number - The stroke width in pixels
visible Boolean true Whether this polyline is visible on the map
zIndex Number 0 The zIndex compared to other polys

** Note this is one of those things you're surprised Google couldn't do right. It doesn't take images like all the rest of the icon properties of other components. Here's their example
*** All CSS3 colors are supported except for extended named colors

<template>
  <gmaps-map>
    <gmaps-polygon :path="items" :strokeColor="blue" :fillColor="red" />
    <gmaps-polyline :path="items" :strokeColor="blue" />
  </gmaps-map>
</template>

<script>
  import { gmapsMap, gmapsPolyline, gmapsPolygon } from 'x5-gmaps'

  export default {
    components: { gmapsMap, gmapsPolyline, gmapsPolygon },
    data: () => ({
      items: [
        { lat: -27.41, lng: 153.01 },
        { lat: -27.42, lng: 153.02 },
        ...,
        { lat: -27.48, lng: 153.08 },
        { lat: -27.49, lng: 153.09 },
      ],
    }),
  }
</script>

Rectangles / Circles

Rectangles/Circles

Rectangles/circles are placed within Maps and have several props which are derived from Google's Rectangle Options and Circle Options.

This component supports the following events:

Props Type Default Description
bounds Array required (Only rectangles) Position of rectangle: { east, north, south, west } (Type: google.maps.LatLngBoundsLiteral)
center Object required (Only circles) The center of circle: { lat: number, lng: number } (Type: google.maps.LatLngLiteral)
radius Number required (Only circles) The radius in meters on the Earth's surface
clickable Boolean true Indicates whether this Polyline handles mouse events
draggable Boolean false Allow the shape to be dragged over the map
editable Boolean false Allow editing the shape by dragging the control points
fillColor String black The fill color ***
fillOpacity Number 0.3 The fill opacity between 0.0 and 1.0
strokeColor String black The stroke color ***
strokePosition Number 0 The stroke position along the path (0 = CENTER / 1 = INSIDE / 2 = OUTSIDE)
strokeOpacity Number 1.0 The stroke opacity between 0.0 and 1.0
strokeWeight Number - The stroke width in pixels
visible Boolean true Whether this polyline is visible on the map
zIndex Number 0 The zIndex compared to other polys

*** All CSS3 colors are supported except for extended named colors

<template>
  <gmaps-map>
    <gmaps-rectangle :bounds="bounds" :strokeColor="blue" :fillColor="red" />
    <gmaps-circle
      :center="center"
      :radius="radius"
      :strokeColor="green"
      :fillColor="yellow"
    />
  </gmaps-map>
</template>

<script>
  import { gmapsMap, gmapsRectangle, gmapsCircle } from 'x5-gmaps';

  export default {
    components: { gmapsMap, gmapsPolyline, gmapsPolygon },
    data: () => ({
      bounds: {
        east: 153.12,
        north: -27.44,
        west: 153.0,
        south: -27.58
      },
      center: { lat: -27.479, lng: 152.937 },
      radius: 5000
    })
  };
</script>

Data / GeoJSON

Data / GeoJSON

GeoJSON is an open standard format designed for representing simple geographical features, along with their non-spatial attributes. It can be used in Google Maps, and now in this libary using two new components: GmapsData, and GmapsDataGeoJson.

Because of how Google implements this feature, this library limits you to only one GmapsData element per map. That element will take any global styles and emit all the event listeners. The GmapsDataGeoJson is the element where actual GeoJSON data can be added, along with any overriding styles.

The full Google Maps API for Data has not been incorporated (no drawing yet), but it's certainly able to display any GeoJSON you have.

GmapsData supports the following events: @click, contextmenu, @dblclick, mousedown, mouseout, mouseover, mouseup, rightclick (which are most of those available)

Each returns Google's google.maps.data.MouseEvent which includes the feature hit and latLng.

GmapsData presently only takes an options prop which is of type google.maps.data.StyleOptions. This will effectively be the default style for all Features imported into the data. To override this, you need to set the options for the individual Feature in the GmapsDataGeoJson component.

GmapsDataGeoJson does not have events (all events are emited together from the GmapsData if you include it).

GmapsData also only takes an options prop which is of type google.maps.data.StyleOptions. This is the override style for the Feature(s) defined in this component..

Props Type Default Description
geoJson Object - A parsed GeoJSON object
options google.maps.data.StyleOptions - This is the override style for the Feature(s) defined in this component.
<template>
  <gmaps-map>
    <gmaps-data>
      <gmaps-data-geo-json :geo-json="geoJson" />
      <gmaps-data-geo-json :geo-json="geoJson2" :options="geoJson2Style" />
    </gmaps-data>
  </gmaps-map>
</template>

<script>
  import { gmapsMap, gmapsData, gmapsDataGeoJson } from 'x5-gmaps';

  import geoJson from '../../../public/data/geoJsonData.json';
  import geoJsonL from '../../../public/data/geoJsonDataL.json';

  export default {
    name: 'ExampleGeoJson',
    components: { gmapsMap, gmapsData, gmapsDataGeoJson },
    data: () => ({
      geoJson,
      geoJsonL,
      geoJsonLStyle: { fillColor: 'black' }
    })
  };
</script>



Accessing the Google Maps API

While this should rarely be needed, if you need to access the Google Maps API, you must wait for it to be inserted and loaded. A promised is provided which should return that API when it's ready by importing gmaps (e.g. import { gmaps } from 'x5-gmaps'). Usually it should already be loaded and available via window.google.maps.

The return of this promise is the maps object of the google object most of Google's examples use.

// Example
import { gmaps } from 'x5-gmaps';

export default {
  data: () => ({
    GooglePlacesService: null
  }),
  mounted() {
    gmaps().then(maps => {
      PlacesService = new maps.places.AutocompleteService();
    });
  }
};

Google Places Library

As mentioned above, additional libraries can be used in conjunction with this package, and as an example, this is how you would include the Places Library.

// main.js
Vue.use(x5GMaps, { key: 'YOUR_GOOGLE_KEY', libraries: ['places'] });


Custom map slots

While you shouldn't see these for too long while the map loads (if at all), there are two customisable slots: Loading and Error.

<template>
  <gmaps-map>
    <template v-slot:loading>
      <div>
        <span>This is now loading...</span>
      </div>
    </template>
    <template v-slot:error="{ error }">
      <div>
        <span>You broke it: {{ error }}</span>
      </div>
    </template>
  </gmaps-map>
</template>


Authors

License

This project is licensed under the MIT License - see the LICENSE.md file for details