Menu

Creating a google map with markers component with Vue js / TypeScript

I had to port google map JavaScript API to Vue js, that can pass in Lat/Long list, and other parameters.

Before we get into the component, remember to include the Google API map javascript in the main .html file

<script src="https://maps.googleapis.com/maps/api/js?key=YOURKEY"></script>

Below is the completed component.

<template>
    <div class="map" ref="googleMap"></div>
</template>

<script lang="ts">
import Vue from "vue";
import Component from "vue-class-component";
import { RouteURL } from "../../../shared/constants";
import { urlHelper } from "../../../shared/urlHelper";
import ILocation } from "../shared/models";
declare var google: any;
@Component({
  components: {},
  props: {
    locations: {
      type: Object,
      required: true
    },
    disableDefaultUI: {
      type: Boolean,
      required: true
    },
    zoom: {
      type: Number,
      required: true
    },
    scaleControl: {
      type: Boolean,
      required: true
    },
    zoomControl: {
      type: Boolean,
      required: true
    }   
  }
})
export default class GoogleMapWithMarkersComponent extends Vue {
  map: any;
  markers: any = [];
  bounds = new google.maps.LatLngBounds();
  imagePath: string = "/assets/img/pins/";

  created(){
    // Can't do it here DOM is NOT ready    
  }

  mounted() {
    this.map = this.initMap(); // have to wait untill DOM is ready    
    this.drawMap(this.map, this.$props.locations)
  }

  drawMap(map: any, locations: ILocation[]){
    this.buildMarkers(map, locations);
    map.fitBounds(this.bounds);
    map.panToBounds(this.bounds);
  }

  initMap(): any {
    const element: any = this.$refs.googleMap;
    return new google.maps.Map(element, {
      zoom: this.$props.zoom,
      center: new google.maps.LatLng(-37.7936532, 144.9637612),
      disableDefaultUI: this.$props.disableDefaultUI,
      mapTypeId: google.maps.MapTypeId.ROADMAP,
      gestureHandling: "greedy",     
      scaleControl:this.$props.scaleControl,
      zoomControl:this.$props.zoomControl
    });
  }

  buildMarkers(map: any, locations: ILocation[]) {
    this.bounds = new google.maps.LatLngBounds();
    for (let location of locations) {
       var marker: any =  this.constructMarker(map, location.Latitude, location.Longitude, `${this.imagePath}blue.png`);
       this.bounds.extend(marker.getPosition());
    }
  }

  constructMarker(map: any, latitude: number, longitude: number, icon: string): any{
   return new google.maps.Marker({
        position: new google.maps.LatLng(latitude, longitude),
        icon: { url: icon, scaledSize: new google.maps.Size(27, 43) },
        map: map
      });
  }

}
</script>
<style scoped>
.map {
  border-radius: 8px;
  height: 300px;
}
</style>

Now you can use it like this parent component

<Map :name="'locations'" 
     :locations="locations" 
     :disableDefaultUI="true" 
     :zoom="12" 
     :scaleControl="false" 
     :zoomControl="false"></Map>

There you go, hope this will help anyone looking for a map integration to Vue js.

Leave a comment