Last active
January 12, 2022 13:39
-
-
Save felixranesberger/f34152109e5bc2c65801ed0ba5e5c587 to your computer and use it in GitHub Desktop.
Vue3 Google Map Setup
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<template> | |
<div class="o-container o-container--fullwidth frame-space-bottom-small"> | |
<GMapMap | |
:options="{ | |
styles: mapStyle, | |
}" | |
:center="props.mapData.mapCenter" | |
:zoom="props.mapData.mapZoom" | |
styles="width: 100%; height: 500px" | |
> | |
<GMapMarker | |
v-for="(marker, index) in props.mapData.markers" | |
:key="index" | |
:position="marker.position" | |
:clickable="true" | |
:draggable="false" | |
:icon="getMarkerIcon(marker.icon)" | |
@click="emitMarkerChange(index)" | |
@keyup.enter="emitMarkerChange(index)" | |
@keyup.space="emitMarkerChange(index)" | |
> | |
<GMapInfoWindow | |
:opened="props.openMarkerId === index" | |
> | |
<p> | |
<strong | |
class="vue-map-marker__heading" | |
v-html="marker.name" | |
/> | |
</p> | |
<p | |
class="vue-map-marker__description" | |
v-html="marker.address" | |
/> | |
<div v-html="marker.additionalMarkerContent" /> | |
<a | |
v-if="marker.externalDetailPage" | |
:href="marker.externalDetailPage" | |
> | |
Details | |
</a> | |
</GMapInfoWindow> | |
</GMapMarker> | |
</GMapMap> | |
</div> | |
</template> | |
<script setup> | |
import { watch } from 'vue'; | |
import mapStyle from '../map-style'; | |
const props = defineProps({ | |
mapData: { | |
type: Object, | |
required: true, | |
}, | |
openMarkerId: { | |
type: [ Number, null ], | |
required: true, | |
}, | |
}); | |
const emit = defineEmits([ 'update:active-marker' ]); | |
watch( | |
() => props.openMarkerId, | |
() => { | |
/** | |
* I have to add the event manually because I don't have access to the button and only then should the event be fired. | |
* I need the 500ms waiting time because the button is only added to the DOM and is not yet there right at the beginning. | |
*/ | |
setTimeout(() => { | |
const elements = document.querySelectorAll('.gm-ui-hover-effect'); | |
if (!elements) return; | |
Array.from(elements).forEach((closeButton) => { | |
closeButton.addEventListener('click', () => { | |
emitMarkerChange(null); | |
}); | |
}); | |
}, 500); | |
} | |
); | |
const emitMarkerChange = id => { | |
emit('update:active-marker', id); | |
}; | |
const getMarkerIcon = icon => { | |
if (!icon) return ''; | |
return { | |
url: icon, | |
scaledSize: { | |
width: 32, | |
height: 32, | |
}, | |
}; | |
}; | |
</script> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const style = [ | |
{ | |
'elementType': 'geometry', | |
'stylers': [ | |
{ | |
'color': '#f5f5f5' | |
} | |
] | |
}, | |
{ | |
'elementType': 'labels.icon', | |
'stylers': [ | |
{ | |
'visibility': 'off' | |
} | |
] | |
}, | |
{ | |
'elementType': 'labels.text.fill', | |
'stylers': [ | |
{ | |
'color': '#616161' | |
} | |
] | |
}, | |
{ | |
'elementType': 'labels.text.stroke', | |
'stylers': [ | |
{ | |
'color': '#f5f5f5' | |
} | |
] | |
}, | |
{ | |
'featureType': 'administrative.land_parcel', | |
'elementType': 'labels.text.fill', | |
'stylers': [ | |
{ | |
'color': '#bdbdbd' | |
} | |
] | |
}, | |
{ | |
'featureType': 'poi', | |
'elementType': 'geometry', | |
'stylers': [ | |
{ | |
'color': '#eeeeee' | |
} | |
] | |
}, | |
{ | |
'featureType': 'poi', | |
'elementType': 'labels.text.fill', | |
'stylers': [ | |
{ | |
'color': '#757575' | |
} | |
] | |
}, | |
{ | |
'featureType': 'poi.park', | |
'elementType': 'geometry', | |
'stylers': [ | |
{ | |
'color': '#e5e5e5' | |
} | |
] | |
}, | |
{ | |
'featureType': 'poi.park', | |
'elementType': 'labels.text.fill', | |
'stylers': [ | |
{ | |
'color': '#9e9e9e' | |
} | |
] | |
}, | |
{ | |
'featureType': 'road', | |
'elementType': 'geometry', | |
'stylers': [ | |
{ | |
'color': '#ffffff' | |
} | |
] | |
}, | |
{ | |
'featureType': 'road.arterial', | |
'elementType': 'labels.text.fill', | |
'stylers': [ | |
{ | |
'color': '#757575' | |
} | |
] | |
}, | |
{ | |
'featureType': 'road.highway', | |
'elementType': 'geometry', | |
'stylers': [ | |
{ | |
'color': '#dadada' | |
} | |
] | |
}, | |
{ | |
'featureType': 'road.highway', | |
'elementType': 'labels.text.fill', | |
'stylers': [ | |
{ | |
'color': '#616161' | |
} | |
] | |
}, | |
{ | |
'featureType': 'road.local', | |
'elementType': 'labels.text.fill', | |
'stylers': [ | |
{ | |
'color': '#9e9e9e' | |
} | |
] | |
}, | |
{ | |
'featureType': 'transit.line', | |
'elementType': 'geometry', | |
'stylers': [ | |
{ | |
'color': '#e5e5e5' | |
} | |
] | |
}, | |
{ | |
'featureType': 'transit.station', | |
'elementType': 'geometry', | |
'stylers': [ | |
{ | |
'color': '#eeeeee' | |
} | |
] | |
}, | |
{ | |
'featureType': 'water', | |
'elementType': 'geometry', | |
'stylers': [ | |
{ | |
'color': '#c9c9c9' | |
} | |
] | |
}, | |
{ | |
'featureType': 'water', | |
'elementType': 'labels.text.fill', | |
'stylers': [ | |
{ | |
'color': '#9e9e9e' | |
} | |
] | |
} | |
]; | |
export default style; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment