# Conflicts:
#	docs/package-lock.json
This commit is contained in:
Fawad Mirzad
2021-02-14 07:38:21 +01:00
25 changed files with 319 additions and 173 deletions

View File

@@ -47,30 +47,31 @@ module.exports = {
{ {
title: 'Getting started', title: 'Getting started',
path: '/docs/', path: '/docs/',
sidebarDepth: 2, sidebarDepth: 0,
collapsable: false, collapsable: false,
children: [ children: [
'/docs/introduction',
'/docs/getting-started',
] ]
}, },
{ {
title: 'Components', title: 'Components',
collapsable: false, collapsable: false,
path: '/components/', path: '/components/',
sidebarDepth: 2, sidebarDepth: 0,
children: [ children: [
'/components/introduction', '/components/introduction',
'/components/map', '/components/map',
'/components/marker', '/components/marker',
'/components/info-window', '/components/info-window',
'/components/cluster',
'/components/polygon',
'/components/rectangle',
] ]
}, },
{ {
title: 'Advanced', title: 'Advanced',
collapsable: false, collapsable: false,
path: '/advanced/', path: '/advanced/',
sidebarDepth: 2, sidebarDepth: 0,
children: [ children: [
'/advanced/introduction', '/advanced/introduction',
] ]

View File

@@ -1,10 +1,19 @@
# List # Components
`@fawmi/vue-google-maps` provides a set of Vue.js 3 components wrapping the Google Maps API v3. `@fawmi/vue-google-maps` provides a set of Vue.js 3 components wrapping the Google Maps API v3.
Currently `Map`, `Marker`, `InfoWindow`, `Polygon` and `Rectangle` are supported. Currently `Map`, `Marker`, `InfoWindow`, `Cluster`, `Polygon` and `Rectangle` are supported.
Other components are still under development. Checkout the docs page for each component to see how to use it.
[Map](./map.md)
Checkout getting started to read, how to install and use vue-google-maps [Marker](./marker.md)
[InfoWindow](./info-window.md)
[Cluster](./cluster.md)
[Polygon](./polygon.md)
[Rectangle](./rectangle.md)

View File

@@ -0,0 +1,44 @@
# Cluster
To cluster objects you simply wrap your markers with the cluster component.
```vue
<template>
<GmapMap
:center="center"
:zoom="7"
map-type-id="terrain"
style="width: 500px; height: 300px"
>
<GmapCluster>
<GmapMarker
:key="index"
v-for="(m, index) in markers"
:position="m.position"
:clickable="true"
:draggable="true"
@click="center=m.position"
/>
</GmapCluster>
</GmapMap>
</template>
<script>
export default {
name: 'App',
data() {
return {
center: {lat: 51.093048, lng: 6.842120},
markers: [
{
position: {
lat: 51.093048, lng: 6.842120
},
}
, // Along list of clusters
]
}
}
}
</script>
```

View File

@@ -1,10 +1,19 @@
# Component list # Components
`@fawmi/vue-google-maps` provides a set of Vue.js 3 components wrapping the Google Maps API v3. `@fawmi/vue-google-maps` provides a set of Vue.js 3 components wrapping the Google Maps API v3.
Currently `Map`, `Marker`, `InfoWindow`, `Polygon` and `Rectangle` are supported. Currently `Map`, `Marker`, `InfoWindow`, `Cluster`, `Polygon` and `Rectangle` are supported.
Other components are still under development. Checkout the docs page for each component to see how to use it.
[Map](./map.md)
Checkout getting started to read, how to install and use vue-google-maps [Marker](./marker.md)
[InfoWindow](./info-window.md)
[Cluster](./cluster.md)
[Polygon](./polygon.md)
[Rectangle](./rectangle.md)

View File

@@ -0,0 +1,2 @@
# Polygon
Polygon is a simple wrapper around google's polygon component.

View File

@@ -0,0 +1,3 @@
# Rectangle
Polygon is a simple wrapper around google's polygon component.

View File

@@ -2,9 +2,59 @@
`@fawmi/vue-google-maps` provides a set of Vue.js 3 components wrapping the Google Maps API v3. `@fawmi/vue-google-maps` provides a set of Vue.js 3 components wrapping the Google Maps API v3.
Currently `Map`, `Marker`, `InfoWindow`, `Polygon` and `Rectangle` are supported. The following components are currently supported:
Other components are still under development. `Map`, `Marker`, `Cluster`, `InfoWindow`, `Polygon`, `Rectangle`
Checkout getting started to read, how to install and use vue-google-maps Checkout getting started to read, how to install and use vue-google-maps
# Install and configure
to install it via NPM
```bash
npm install -S @fawmi/vue-google-maps
```
## Basic usage
You need an API Key. Learn how to [get an Api key ](https://developers.google.com/maps/documentation/javascript/get-api-key).
##Configure Vue to use the Components
Initialise the plugin in your `main.js`:
```js
import { createApp } from 'vue'
import * as VueGoogleMaps from '@fawmi/vue-google-maps'
const app = createApp(App);
app.use(VueGoogleMaps, {
load: {
key: 'YOUR_API_KEY_COMES_HERE',
},
}).mount('#app')
```
## Use it anywhere in your components
```vue
<template>
<GmapMap
:center="{lat: 51.093048, lng: 6.842120}"
:zoom="7"
map-type-id="terrain"
style="width: 100vw; height: 900px"
>
</GmapMap>
</template>
<script >
export default {
name: 'App',
data() {
return {
center: {lat: 51.093048, lng: 6.842120},
}
}
}
</script>
```

View File

@@ -1,38 +1,60 @@
# Introduction
`@fawmi/vue-google-maps` provides a set of Vue.js 3 components wrapping the Google Maps API v3.
The following components are currently supported:
`Map`, `Marker`, `Cluster`, `InfoWindow`, `Polygon`, `Rectangle`
Checkout getting started to read, how to install and use vue-google-maps
# Install and configure # Install and configure
## Install to install it via NPM
to install it via NPM
```bash ```bash
npm install -S @fawmi/vue-google-maps npm install -S @fawmi/vue-google-maps
``` ```
You can also install via Yarn
```bash
yarn add @fawmi/vue-google-maps
```
## Example ## Basic usage
Here is a basic example You need an API Key. Learn how to [get an Api key ](https://developers.google.com/maps/documentation/javascript/get-api-key).
```javascript ##Configure Vue to use the Components
Initialise the plugin in your `main.js`:
```js
import { createApp } from 'vue' import { createApp } from 'vue'
import googleMap from '@fawmi/vue-google-maps' import * as VueGoogleMaps from '@fawmi/vue-google-maps'
import App from './App.vue';
const googleMapOption = {
apiKey: 'here_comes_your_api_key',
}
const app = createApp(App); const app = createApp(App);
app.use(VueGoogleMaps, {
app.use(googleMap, googleMapOption) load: {
app.mount('#app') key: 'YOUR_API_KEY_COMES_HERE',
},
}).mount('#app')
``` ```
## Options ## Use it anywhere in your components
apiKey is required option to load maps, you may provide following additional options if you want.
###`mapIds` ```vue
Allows you to style the map using google cloud map styling <template>
<GmapMap
:center="{lat: 51.093048, lng: 6.842120}"
:zoom="7"
map-type-id="terrain"
style="width: 100vw; height: 900px"
>
</GmapMap>
</template>
<script >
export default {
name: 'App',
data() {
return {
center: {lat: 51.093048, lng: 6.842120},
}
}
}
</script>
```

56
docs/src/docs/introduction.md Executable file → Normal file
View File

@@ -2,9 +2,59 @@
`@fawmi/vue-google-maps` provides a set of Vue.js 3 components wrapping the Google Maps API v3. `@fawmi/vue-google-maps` provides a set of Vue.js 3 components wrapping the Google Maps API v3.
Currently `Map`, `Marker`, `InfoWindow`, `Polygon` and `Rectangle` are supported. The following components are currently supported:
Other components are still under development. `Map`, `Marker`, `Cluster`, `InfoWindow`, `Polygon`, `Rectangle`
Checkout getting started to read, how to install and use vue-google-maps Checkout getting started to read, how to install and use vue-google-maps
# Install and configure
to install it via NPM
```bash
npm install -S @fawmi/vue-google-maps
```
## Basic usage
You need an API Key. Learn how to [get an Api key ](https://developers.google.com/maps/documentation/javascript/get-api-key).
##Configure Vue to use the Components
Initialise the plugin in your `main.js`:
```js
import { createApp } from 'vue'
import * as VueGoogleMaps from '@fawmi/vue-google-maps'
const app = createApp(App);
app.use(VueGoogleMaps, {
load: {
key: 'YOUR_API_KEY_COMES_HERE',
},
}).mount('#app')
```
## Use it anywhere in your components
```vue
<template>
<GmapMap
:center="{lat: 51.093048, lng: 6.842120}"
:zoom="7"
map-type-id="terrain"
style="width: 100vw; height: 900px"
>
</GmapMap>
</template>
<script >
export default {
name: 'App',
data() {
return {
center: {lat: 51.093048, lng: 6.842120},
}
}
}
</script>
```

View File

@@ -145,7 +145,7 @@ If you need to gain access to the `google` object, you can access it by getting
/> />
</template> </template>
<script> <script>
import {gmapApi} from 'vue2-google-maps' import {gmapApi} from '@fawmi/vue-google-maps'
export default { export default {
mounted() { mounted() {

View File

@@ -1,8 +0,0 @@
{
"presets": ["@babel/preset-env"],
"plugins": [
"@babel/plugin-proposal-object-rest-spread",
"transform-inline-environment-variables",
"minify-dead-code-elimination"
]
}

View File

@@ -1,9 +1,6 @@
/* vim: set softtabstop=2 shiftwidth=2 expandtab : */
<template> <template>
<div> <div>
<div ref="flyaway"> <div ref="infoWindow">
<!-- so named because it will fly away to another component -->
<slot> </slot> <slot> </slot>
</div> </div>
</div> </div>
@@ -51,12 +48,12 @@ export default mapElementFactory({
}, },
mounted() { mounted() {
const el = this.$refs.flyaway const el = this.$refs.infoWindow
el.parentNode.removeChild(el) el.parentNode.removeChild(el)
}, },
beforeCreate(options) { beforeCreate(options) {
options.content = this.$refs.flyaway options.content = this.$refs.infoWindow
if (this.$markerPromise) { if (this.$markerPromise) {
delete options.position delete options.position

View File

@@ -54,7 +54,7 @@ export default mapElementFactory({
}, },
afterCreate(inst) { afterCreate(inst) {
var clearEvents = () => {} let clearEvents = () => {}
// Watch paths, on our own, because we do not want to set either when it is // Watch paths, on our own, because we do not want to set either when it is
// empty // empty

View File

@@ -45,7 +45,7 @@ export default mapElementFactory({
ctr: () => google.maps.Polyline, ctr: () => google.maps.Polyline,
afterCreate() { afterCreate() {
var clearEvents = () => {} let clearEvents = () => {}
this.$watch( this.$watch(
'path', 'path',

18
src/load-google-maps.js Normal file
View File

@@ -0,0 +1,18 @@
import {Env} from "@/utils/env";
import {createMapScript} from "@/utils/create-map-script";
let isApiSetUp = false
export function loadGMapApi (options) {
if (Env.isServer()) {
return;
}
if (!isApiSetUp) {
isApiSetUp = true
const googleMapScript = createMapScript(options);
document.head.appendChild(googleMapScript)
} else {
throw new Error('You already started the loading of google maps')
}
}

View File

@@ -1,5 +1,5 @@
import lazy from './utils/lazyValue' import lazy from './utils/lazyValue'
import { loadGmapApi } from './manager' import { loadGMapApi } from './load-google-maps'
import { createApp } from 'vue' import { createApp } from 'vue'
import Marker from './components/marker' import Marker from './components/marker'
import Polyline from './components/polyline' import Polyline from './components/polyline'
@@ -14,11 +14,11 @@ import Autocomplete from './components/autocomplete.vue'
import MapElementMixin from './components/mapElementMixin' import MapElementMixin from './components/mapElementMixin'
import MapElementFactory from './components/mapElementFactory' import MapElementFactory from './components/mapElementFactory'
import MountableMixin from './utils/mountableMixin' import MountableMixin from './utils/mountableMixin'
import {Env} from "./utils/env";
let GmapApi = null let GmapApi = null
// export everything
export { export {
loadGmapApi, loadGMapApi,
Marker, Marker,
Polyline, Polyline,
Polygon, Polygon,
@@ -34,18 +34,12 @@ export {
} }
export function install(Vue, options) { export function install(Vue, options) {
// Set defaults
options = { options = {
installComponents: true, installComponents: true,
autobindAllEvents: false, autobindAllEvents: false,
...options, ...options,
} }
// Update the global `GmapApi`. This will allow
// components to use the `google` global reactively
// via:
// import {gmapApi} from 'vue2-google-maps'
// export default { computed: { google: gmapApi } }
GmapApi = createApp({ GmapApi = createApp({
data: function () { data: function () {
return { gmapApi: null } return { gmapApi: null }
@@ -93,14 +87,13 @@ function makeGmapApiPromiseLazy(options) {
return lazy(() => { return lazy(() => {
// Load the // Load the
// This will only be evaluated once // This will only be evaluated once
if (typeof window === 'undefined') { if (Env.isServer()) {
// server side -- never resolve this promise
return new Promise(() => {}).then(onApiLoaded) return new Promise(() => {}).then(onApiLoaded)
} else { } else {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
try { try {
window['vueGoogleMapsInit'] = resolve window['vueGoogleMapsInit'] = resolve
loadGmapApi(options.load, options.loadCn) loadGMapApi(options.load)
} catch (err) { } catch (err) {
reject(err) reject(err)
} }
@@ -112,8 +105,7 @@ function makeGmapApiPromiseLazy(options) {
// end-users with the global `vueGoogleMapsInit: () => undefined` // end-users with the global `vueGoogleMapsInit: () => undefined`
// when the Google Maps API has been loaded // when the Google Maps API has been loaded
const promise = new Promise((resolve) => { const promise = new Promise((resolve) => {
if (typeof window === 'undefined') { if (Env.isServer()) {
// Do nothing if run from server-side
return return
} }
window['vueGoogleMapsInit'] = resolve window['vueGoogleMapsInit'] = resolve

View File

@@ -1,76 +0,0 @@
let isApiSetUp = false
/**
* @param apiKey API Key, or object with the URL parameters. For example
* to use Google Maps Premium API, pass
* `{ client: <YOUR-CLIENT-ID> }`.
* You may pass the libraries and/or version (as `v`) parameter into
* this parameter and skip the next two parameters
* @param version Google Maps version
* @param libraries Libraries to load (@see
* https://developers.google.com/maps/documentation/javascript/libraries)
* @param loadCn Boolean. If set to true, the map will be loaded from google maps China
* (@see https://developers.google.com/maps/documentation/javascript/basics#GoogleMapsChina)
*
* Example:
* ```
* import {load} from 'vue-google-maps'
*
* load(<YOUR-API-KEY>)
*
* load({
* key: <YOUR-API-KEY>,
* })
*
* load({
* client: <YOUR-CLIENT-ID>,
* channel: <YOUR CHANNEL>
* })
* ```
*/
export const loadGmapApi = (options, loadCn) => {
if (typeof document === 'undefined') {
// Do nothing if run from server-side
return
}
if (!isApiSetUp) {
isApiSetUp = true
const googleMapScript = document.createElement('SCRIPT')
// Allow options to be an object.
// This is to support more esoteric means of loading Google Maps,
// such as Google for business
// https://developers.google.com/maps/documentation/javascript/get-api-key#premium-auth
if (typeof options !== 'object') {
throw new Error('options should be an object')
}
// libraries
/* eslint-disable no-prototype-builtins */
if (Array.prototype.isPrototypeOf(options.libraries)) {
options.libraries = options.libraries.join(',')
}
options['callback'] = 'vueGoogleMapsInit'
let baseUrl = 'https://maps.googleapis.com/'
if (typeof loadCn === 'boolean' && loadCn === true) {
baseUrl = 'https://maps.google.cn/'
}
let url =
baseUrl +
'maps/api/js?' +
Object.keys(options)
.map((key) => encodeURIComponent(key) + '=' + encodeURIComponent(options[key]))
.join('&')
googleMapScript.setAttribute('src', url)
googleMapScript.setAttribute('async', '')
googleMapScript.setAttribute('defer', '')
document.head.appendChild(googleMapScript)
} else {
throw new Error('You already started the loading of google maps')
}
}

View File

@@ -1,8 +1,5 @@
import WatchPrimitiveProperties from '../utils/WatchPrimitiveProperties' import WatchPrimitiveProperties from '../utils/WatchPrimitiveProperties'
import {Str} from "./string";
function capitalizeFirstLetter(string) {
return string.charAt(0).toUpperCase() + string.slice(1)
}
export function getPropsValues(vueInst, props) { export function getPropsValues(vueInst, props) {
return Object.keys(props).reduce((acc, prop) => { return Object.keys(props).reduce((acc, prop) => {
@@ -26,8 +23,8 @@ export function bindProps(vueInst, googleMapsInst, props) {
if (noBind) continue if (noBind) continue
const setMethodName = 'set' + capitalizeFirstLetter(attribute) const setMethodName = 'set' + Str.capitalizeFirstLetter(attribute)
const getMethodName = 'get' + capitalizeFirstLetter(attribute) const getMethodName = 'get' + Str.capitalizeFirstLetter(attribute)
const eventName = attribute.toLowerCase() + '_changed' const eventName = attribute.toLowerCase() + '_changed'
const initialValue = vueInst[attribute] const initialValue = vueInst[attribute]
@@ -42,8 +39,7 @@ export function bindProps(vueInst, googleMapsInst, props) {
// although this may really be the user's responsibility // although this may really be the user's responsibility
if (type !== Object || !trackProperties) { if (type !== Object || !trackProperties) {
// Track the object deeply // Track the object deeply
vueInst.$watch( vueInst.$watch(attribute,
attribute,
() => { () => {
const attributeValue = vueInst[attribute] const attributeValue = vueInst[attribute]

View File

@@ -0,0 +1,25 @@
export function createMapScript(options) {
const googleMapScript = document.createElement('SCRIPT')
if (typeof options !== 'object') {
throw new Error('options should be an object')
}
// libraries
/* eslint-disable no-prototype-builtins */
if (Array.prototype.isPrototypeOf(options.libraries)) {
options.libraries = options.libraries.join(',')
}
options['callback'] = 'vueGoogleMapsInit'
let baseUrl = 'https://maps.googleapis.com/maps/api/js?'
let url =
baseUrl +
Object.keys(options)
.map((key) => encodeURIComponent(key) + '=' + encodeURIComponent(options[key])).join('&')
googleMapScript.setAttribute('src', url)
googleMapScript.setAttribute('async', '')
googleMapScript.setAttribute('defer', '')
return googleMapScript;
}

5
src/utils/env.js Normal file
View File

@@ -0,0 +1,5 @@
export class Env {
static isServer() {
return typeof document === 'undefined';
}
}

3
src/utils/event.js Normal file
View File

@@ -0,0 +1,3 @@
export class eventUtils {
}

View File

@@ -1,16 +1,15 @@
// This piece of code was orignally written by sindresorhus and can be seen here // lazy-value by sindresorhus
// https://github.com/sindresorhus/lazy-value/blob/master/index.js
export default (fn) => { module.exports = fn => {
let called = false let called = false;
let ret let result;
return () => { return () => {
if (!called) { if (!called) {
called = true called = true;
ret = fn() result = fn();
} }
return ret return result;
} };
} };

View File

@@ -2,17 +2,17 @@
// http://stackoverflow.com/a/11703018/2694653 // http://stackoverflow.com/a/11703018/2694653
// This has been ported to Vanilla.js by GuillaumeLeclerc // This has been ported to Vanilla.js by GuillaumeLeclerc
export default (input) => { export default (input) => {
var _addEventListener = input.addEventListener ? input.addEventListener : input.attachEvent const _addEventListener = input.addEventListener ? input.addEventListener : input.attachEvent
function addEventListenerWrapper(type, listener) { function addEventListenerWrapper(type, listener) {
// Simulate a 'down arrow' keypress on hitting 'return' when no pac suggestion is selected, // Simulate a 'down arrow' keypress on hitting 'return' when no pac suggestion is selected,
// and then trigger the original listener. // and then trigger the original listener.
if (type === 'keydown') { if (type === 'keydown') {
var origListener = listener const origListener = listener
listener = function (event) { listener = function (event) {
var suggestionSelected = document.getElementsByClassName('pac-item-selected').length > 0 const suggestionSelected = document.getElementsByClassName('pac-item-selected').length > 0
if (event.which === 13 && !suggestionSelected) { if (event.which === 13 && !suggestionSelected) {
var simulatedEvent = document.createEvent('Event') const simulatedEvent = document.createEvent('Event')
simulatedEvent.keyCode = 40 simulatedEvent.keyCode = 40
simulatedEvent.which = 40 simulatedEvent.which = 40
origListener.apply(input, [simulatedEvent]) origListener.apply(input, [simulatedEvent])

5
src/utils/string.js Normal file
View File

@@ -0,0 +1,5 @@
export class Str {
static capitalizeFirstLetter(string) {
return string.charAt(0).toUpperCase() + string.slice(1)
}
}

View File

@@ -17,7 +17,7 @@
<script src="../../dist/vue-google-maps.js"></script> <script src="../../dist/vue-google-maps.js"></script>
<script> <script>
// This page does not have maps, but we use Vue2-google-maps // This page does not have maps, but we use @fawmi/vue-google-maps
// Must ensure that Google Maps library is NEVER loaded // Must ensure that Google Maps library is NEVER loaded
Vue.use(VueGoogleMaps, { Vue.use(VueGoogleMaps, {
load: { load: {