Security News
New Python Packaging Proposal Aims to Solve Phantom Dependency Problem with SBOMs
PEP 770 proposes adding SBOM support to Python packages to improve transparency and catch hidden non-Python dependencies that security tools often miss.
vue3-google-map
Advanced tools
A set of composable components for easy use of Google Maps in your Vue 3 projects.
Composable components for easy use of Google Maps with Vue 3
vue3-google-map
offers a set of composable components for easy use of Google Maps in your Vue 3 projects.
npm install vue3-google-map
# OR
yarn add vue3-google-map
Include the following script tag in your index.html
(make sure to include it after Vue 3).
<script src="https://unpkg.com/vue3-google-map"></script>
To construct a map using vue3-google-map
you'll need to use the base GoogleMap
component which receives your Google Maps API key, styles (e.g. setting width and height), and any MapOptions to configure your map (see this for a all the supported MapOptions
).
Other map features can be added to your map by passing map subcomponents (Marker, Polyline, Polygon, Rectangle, Circle, InfoWindow, or CustomControl) to the default slot of the GoogleMap
component.
<template>
<GoogleMap api-key="YOUR_GOOGLE_MAPS_API_KEY" style="width: 100%; height: 500px" :center="center" :zoom="15">
<Marker :options="{ position: center }" />
</GoogleMap>
</template>
<script>
import { defineComponent } from "vue";
import { GoogleMap, Marker } from "vue3-google-map";
export default defineComponent({
components: { GoogleMap, Marker },
setup() {
const center = { lat: 40.689247, lng: -74.044502 };
return { center };
},
});
</script>
This library is intended to be used in a composable fashion and therefore you will find yourself using nested components to build your map rather than just a complicated inline format.
The main mapping component is GoogleMap
, however the following components are available at your disposal:
Use the Marker
component to draw markers, drop pins or any custom icons on a map.
You can pass a MarkerOptions object to the options
prop to configure your marker.
<template>
<GoogleMap api-key="YOUR_GOOGLE_MAPS_API_KEY" style="width: 100%; height: 500px" :center="center" :zoom="15">
<Marker :options="markerOptions" />
</GoogleMap>
</template>
<script>
import { defineComponent } from "vue";
import { GoogleMap, Marker } from "vue3-google-map";
export default defineComponent({
components: { GoogleMap, Marker },
setup() {
const center = { lat: 40.689247, lng: -74.044502 };
const markerOptions = { position: center, label: "L", title: "LADY LIBERTY" };
return { center, markerOptions };
},
});
</script>
You can listen for the following events on the Marker
component.
Use the Polyline
component to draw paths and arbitrary shapes on a map.
You can pass a PolylineOptions object to the options
prop to configure your polyline.
<template>
<GoogleMap api-key="YOUR_GOOGLE_MAPS_API_KEY" style="width: 100%; height: 500px" :center="center" :zoom="3">
<Polyline :options="flightPath" />
</GoogleMap>
</template>
<script>
import { defineComponent } from "vue";
import { GoogleMap, Polyline } from "vue3-google-map";
export default defineComponent({
components: { GoogleMap, Polyline },
setup() {
const center = { lat: 0, lng: -180 };
const flightPlanCoordinates = [
{ lat: 37.772, lng: -122.214 },
{ lat: 21.291, lng: -157.821 },
{ lat: -18.142, lng: 178.431 },
{ lat: -27.467, lng: 153.027 },
];
const flightPath = {
path: flightPlanCoordinates,
geodesic: true,
strokeColor: "#FF0000",
strokeOpacity: 1.0,
strokeWeight: 2,
};
return { center, flightPath };
},
});
</script>
You can listen for the following events on the Polyline
component.
Use the Polygon
component to draw polgons (arbitrary number of sides) on a map.
You can pass a PolylgonOptions object to the options
prop to configure your polyline.
<template>
<GoogleMap api-key="YOUR_GOOGLE_MAPS_API_KEY" style="width: 100%; height: 500px" :center="center" :zoom="5">
<Polygon :options="bermudaTriangle" />
</GoogleMap>
</template>
<script>
import { defineComponent } from "vue";
import { GoogleMap, Polygon } from "vue3-google-map";
export default defineComponent({
components: { GoogleMap, Polygon },
setup() {
const center = { lat: 24.886, lng: -70.268 };
const triangleCoords = [
{ lat: 25.774, lng: -80.19 },
{ lat: 18.466, lng: -66.118 },
{ lat: 32.321, lng: -64.757 },
{ lat: 25.774, lng: -80.19 },
];
const bermudaTriangle = {
paths: triangleCoords,
strokeColor: "#FF0000",
strokeOpacity: 0.8,
strokeWeight: 2,
fillColor: "#FF0000",
fillOpacity: 0.35,
};
return { center, bermudaTriangle };
},
});
</script>
You can listen for the following events on the Polygon
component.
Use the Rectangle
component to draw simple rectangles on a map.
You can pass a RectangleOptions object to the options
prop to configure your rectangle.
<template>
<GoogleMap
api-key="YOUR_GOOGLE_MAPS_API_KEY"
style="width: 100%; height: 500px"
mapTypeId="terrain"
:center="center"
:zoom="11"
>
<Rectangle :options="rectangle" />
</GoogleMap>
</template>
<script>
import { defineComponent } from "vue";
import { GoogleMap, Marker } from "vue3-google-map";
export default defineComponent({
components: { GoogleMap, Marker },
setup() {
const center = { lat: 33.678, lng: -116.243 };
const rectangle = {
strokeColor: "#FF0000",
strokeOpacity: 0.8,
strokeWeight: 2,
fillColor: "#FF0000",
fillOpacity: 0.35,
bounds: {
north: 33.685,
south: 33.671,
east: -116.234,
west: -116.251,
},
};
return { center, rectangle };
},
});
</script>
You can listen for the following events on the Rectangle
component.
Use the Circle
component to draw circles on a map.
You can pass a CircleOptions object to the options
prop to configure your circle.
<template>
<GoogleMap
api-key="YOUR_GOOGLE_MAPS_API_KEY"
style="width: 100%; height: 500px"
mapTypeId="terrain"
:center="center"
:zoom="4"
>
<Circle v-for="circle in circles" :options="circle" />
</GoogleMap>
</template>
<script>
import { defineComponent } from "vue";
import { GoogleMap, Circle } from "vue3-google-map";
export default defineComponent({
components: { GoogleMap, Circle },
setup() {
const center = { lat: 37.09, lng: -95.712 };
const cities = {
chicago: {
center: { lat: 41.878, lng: -87.629 },
population: 2714856,
},
newyork: {
center: { lat: 40.714, lng: -74.005 },
population: 8405837,
},
losangeles: {
center: { lat: 34.052, lng: -118.243 },
population: 3857799,
},
vancouver: {
center: { lat: 49.25, lng: -123.1 },
population: 603502,
},
};
const circles = {};
for (const key in cities) {
circles[key] = {
center: cities[key].center,
radius: Math.sqrt(cities[key].population) * 100,
strokeColor: "#FF0000",
strokeOpacity: 0.8,
strokeWeight: 2,
fillColor: "#FF0000",
fillOpacity: 0.35,
};
}
return { center, circles };
},
});
</script>
You can listen for the following events on the Circle
component.
Use the InfoWindow
component to display content in a popup window above the map, at a given location.
You can pass an InfoWindowOptions object to the options
prop to configure your info window. Note that you can optionally pass your content to the default slot of the InfoWindow
component.
<template>
<GoogleMap api-key="YOUR_GOOGLE_MAPS_API_KEY" style="width: 100%; height: 500px" :center="center" :zoom="10">
<InfoWindow :options="{ position: center, content: 'Hello World!' }" />
<InfoWindow :options="{ position: { lat: center.lat, lng: 150.8 } }"> Content passed through slot </InfoWindow>
</GoogleMap>
</template>
<script>
import { defineComponent } from "vue";
import { GoogleMap, InfoWindow } from "vue3-google-map";
export default defineComponent({
components: { GoogleMap, InfoWindow },
setup() {
const center = { lat: -33.9, lng: 151.1 };
return { center };
},
});
</script>
You can nest the InfoWindow
component inside the Marker
component to display an info window when the marker is clicked.
<template>
<GoogleMap api-key="YOUR_GOOGLE_MAPS_API_KEY" style="width: 100%; height: 500px" :center="center" :zoom="4">
<Marker :options="{ position: center }">
<InfoWindow>
<div id="contet">
<div id="siteNotice"></div>
<h1 id="firstHeading" class="firstHeading">Uluru</h1>
<div id="bodyContent">
<p>
<b>Uluru</b>, also referred to as <b>Ayers Rock</b>, is a large sandstone rock formation in the southern
part of the Northern Territory, central Australia. It lies 335 km (208 mi) south west of the
nearest large town, Alice Springs; 450 km (280 mi) by road. Kata Tjuta and Uluru are the two
major features of the Uluru - Kata Tjuta National Park. Uluru is sacred to the Pitjantjatjara and
Yankunytjatjara, the Aboriginal people of the area. It has many springs, waterholes, rock caves and
ancient paintings. Uluru is listed as a World Heritage Site.
</p>
<p>
Attribution: Uluru,
<a href="https://en.wikipedia.org/w/index.php?title=Uluru&oldid=297882194">
https://en.wikipedia.org/w/index.php?title=Uluru</a
>
(last visited June 22, 2009).
</p>
</div>
</div>
</InfoWindow>
</Marker>
</GoogleMap>
</template>
<script>
import { defineComponent } from "vue";
import { GoogleMap, Marker, InfoWindow } from "vue3-google-map";
export default defineComponent({
components: { GoogleMap, Marker, InfoWindow },
setup() {
const center = { lat: -25.363, lng: 131.044 };
return { center };
},
});
</script>
You can listen for the following events on the InfoWindow
component.
Use the CustomControl
component to add custom buttons/controls to your map.
You can define the markup of your custom control in the default
slot of the CustomControl
component. The component itself takes two props:
position
: Defines the position of your custom control on the map. Its value must be one of the ControlPosition constants.index
(optional): Controls the order of placement for custom controls that occupy the same position.Refer to the Google Maps documentation on custom controls positioning.
<template>
<GoogleMap api-key="YOUR_GOOGLE_MAPS_API_KEY" style="width: 100%; height: 500px" :center="center" :zoom="13">
<CustomControl position="BOTTOM_CENTER">
<button class="custom-btn" @click="sayHi">👋</button>
</CustomControl>
</GoogleMap>
</template>
<script>
import { defineComponent } from "vue";
import { GoogleMap, CustomControl } from "vue3-google-map";
export default defineComponent({
components: { GoogleMap, CustomControl },
setup() {
const center = { lat: 35, lng: -95 };
const sayHi = () => alert("Hi!");
return { center, sayHi };
},
});
</script>
<style scoped>
.custom-btn {
box-sizing: border-box;
background: white;
height: 40px;
width: 40px;
border-radius: 2px;
border: 0px;
margin: 10px;
padding: 0px;
font-size: 1.25rem;
text-transform: none;
appearance: none;
cursor: pointer;
user-select: none;
box-shadow: rgba(0, 0, 0, 0.3) 0px 1px 4px -1px;
overflow: hidden;
}
</style>
The basic components that vue3-google-map
provides are fully reactive and will get you pretty far. Should you need to access the Google Maps API, however, the GoogleMaps
component exposes the following:
ready
: A boolean indicating when the Google Maps script has been loaded. By this point the map instance has been created, the API is ready for use and event listeners have been set up on the map.map
: The Map class instance.api
: The Google Maps API.mapTilesLoaded
: A boolean indicating when the map tiles have been fully loaded.Some useage patterns:
<template>
<GoogleMap ref="mapRef">
<template #default="{ ready, api, map, mapTilesLoaded }">
<!-- First pattern: Here you have access to the API and map instance.
"ready" is a boolean that indicates when the Google Maps script
has been loaded and the api and map instance are ready to be used -->
</template>
</GoogleMap>
</template>
<script>
import { defineComponent, ref, computed, watch } from 'vue'
import { GoogleMap } from 'vue3-google-map'
export default defineComponent({
components: { GoogleMap },
setup() {
const mapRef = ref(null)
// Second pattern: compute some value using the API or map instance when "ready"
markerIcon = computed(() => mapRef.value.ready
? {
url: /* icon image url */,
scaledSize: new mapRef.value.api.Size(20, 20)
}
: null)
// Third pattern: watch for "ready" then do something with the API or map instance
watch(() => mapRef.value.ready, (ready) => {
if (!ready) return
// do something with the api using `mapRef.value.api`
// or with the map instance using `mapRef.value.map`
})
return { mapRef }
},
})
</script>
Example:
<template>
<GoogleMap ref="mapRef" api-key="YOUR_GOOGLE_MAPS_API_KEY" class="map" :center="center" :zoom="2" />
<label for="lng">Longitude</label>
<input v-model.number="lng" id="lng" type="number" min="-180" max="180" step="10" />
</template>
<script>
import { defineComponent, ref, computed, watch } from "vue";
import { GoogleMap } from "vue3-google-map";
export default defineComponent({
components: { GoogleMap },
setup() {
const mapRef = ref(null);
const center = { lat: 0, lng: 0 };
const _lng = ref(0);
const lng = computed({
get: () => _lng.value,
set: (v) => {
if (!Number.isFinite(v)) {
_lng.value = 0;
} else if (v > 180) {
_lng.value = 180;
} else if (v < -180) {
_lng.value = -180;
} else {
_lng.value = v;
}
},
});
watch(lng, () => {
if (mapRef.value?.ready) {
mapRef.value.map.panTo({ lat: 0, lng: lng.value });
}
});
return { mapRef, center, lng };
},
});
</script>
<style scoped>
.map {
position: relative;
width: 100%;
height: 500px;
}
.map::after {
position: absolute;
content: "";
width: 1px;
height: 100%;
top: 0;
left: 50%;
background: red;
}
input[type="number"] {
width: 200px;
margin-top: 20px;
margin-left: 10px;
}
</style>
In addition, most of the subcomponents expose their instance should you need it:
Marker
exposes marker
(a Marker class instance).Polyline
exposes polyline
(a Polyline class instance).Polygon
exposes polygon
(a Polygon class instance).Rectangle
exposes rectangle
(a Rectangle class instance).Circle
exposes circle
(a Circle class instance).InfoWindow
exposes infoWindow
(an InfoWindow class instance).All contributions are welcome. Before submitting a PR though it would be nice if you created an issue explaining what you want to acheive and why.
FAQs
A set of composable components for easy use of Google Maps in your Vue 3 projects.
The npm package vue3-google-map receives a total of 18,739 weekly downloads. As such, vue3-google-map popularity was classified as popular.
We found that vue3-google-map demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 0 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
PEP 770 proposes adding SBOM support to Python packages to improve transparency and catch hidden non-Python dependencies that security tools often miss.
Security News
Socket CEO Feross Aboukhadijeh discusses open source security challenges, including zero-day attacks and supply chain risks, on the Cyber Security Council podcast.
Security News
Research
Socket researchers uncover how threat actors weaponize Out-of-Band Application Security Testing (OAST) techniques across the npm, PyPI, and RubyGems ecosystems to exfiltrate sensitive data.