vue3-google-map

repository·develop·Indexed 18 days ago

https://github.com/inocan-group/vue3-google-map

A set of composable Vue 3 components that wrap the Google Maps JavaScript API. It provides a declarative structure for integrating maps and features such as AdvancedMarker, Polyline, Polygon, Rectangle, Circle, InfoWindow, CustomMarker, CustomControl, and MarkerCluster into Vue applications.

Tokens
19.6K
Snippets
64
Records
78
Agent score
57%

What's inside vue3-google-map

  1. Optimize MarkerCluster performance

    develop

    To improve performance, MarkerCluster uses debounced rendering when adding or removing markers.

    • Adjust Debounce Delay: Use the renderDebounceDelay prop (in milliseconds) to control the delay. The default is 10.
    • Force Immediate Rendering: If you need to bypass the debounce and render immediately, access the underlying clusterer via a template ref and call the render() method.
    <script setup>
    import { ref } from 'vue'
    
    const clusterRef = ref()
    
    function forceRender() {
      clusterRef.value?.markerCluster?.render()
    }
    </script>
    
    <template>
      <MarkerCluster ref="clusterRef">
        <!-- markers -->
      </MarkerCluster>
    </template>
  2. Use the composable component architecture of vue3-google-map

    develop

    The library is designed to be used in a composable fashion. Instead of using a single complex configuration object, you should build your map by nesting specialized components inside the main GoogleMap component. This allows for a modular and readable map structure.

    <template>
      <GoogleMap ...>
        <!-- Nest specialized components here -->
        <AdvancedMarker ... />
        <Polyline ... />
      </GoogleMap>
    </template>
  3. How components work in vue3-google-map

    develop
    The library is designed to be used in a composable fashion. Instead of using a single complex configuration object, you build your map by nesting specialized components inside the main GoogleMap component. This allows for a modular and readable declarative structure.
  4. Open and close the InfoWindow programmatically

    develop

    You can manage the visibility of an InfoWindow using v-model. This allows you to programmatically open or close the window and react to its state changes.

    By binding a boolean ref to v-model, the value will automatically update when the user opens or closes the window via map interactions.

    <script setup>
    import { ref, watch } from 'vue';
    import { GoogleMap, Marker, InfoWindow } from 'vue3-google-map';
    
    const center = { lat: -25.363, lng: 131.044 };
    const infowindow = ref(true); // Starts as open
    
    watch(infowindow, (v) => {
      alert('infowindow has been ' + (v ? 'opened' : 'closed'));
    });
    </script>
    
    <template>
      <GoogleMap
        api-key="YOUR_GOOGLE_MAPS_API_KEY"
        style="width: 100%; height: 500px"
        :center="center"
        :zoom="4"
      >
        <Marker :options="{ position: center }">
          <InfoWindow v-model="infowindow">
            <div id="content">This is the infowindow content</div>
          </InfoWindow>
        </Marker>
      </GoogleMap>
    </template>
  5. Use the HeatmapLayer component

    develop

    The HeatmapLayer component is used to depict the intensity of data at geographical points on the map.

    ⚠️ Critical Deprecation Warning

    The Heatmap Layer was removed from the Maps JavaScript API as of version 3.65. To use this component, you must pin the API to version 3.64 or earlier using the version prop on the GoogleMap component.

    Google recommends migrating to a third-party integration like deck.gl for heatmap implementations, as version 3.64 will eventually stop resolving.

    Requirements

    1. Pin API Version: Set version="3.64" on the GoogleMap component.
    2. Include Library: Add 'visualization' to the libraries prop of the GoogleMap component.
    <script setup>
    import { GoogleMap, HeatmapLayer } from 'vue3-google-map'
    
    const sanFrancisco = { lat: 37.774546, lng: -122.433523 }
    
    const heatmapData = [
      { location: { lat: 37.782, lng: -122.447 }, weight: 0.5 },
      { lat: 37.782, lng: -122.445 },
      { location: { lat: 37.782, lng: -122.443 }, weight: 2 },
      { lat: 37.782, lng: -122.441 }, weight: 3 },
      { lat: 37.782, lng: -122.439 }, weight: 2 },
      { lat: 37.782, lng: -122.437 },
      { location: { lat: 37.782, lng: -122.435 }, weight: 0.5 },
    
      { location: { lat: 37.785, lng: -122.447 }, weight: 3 },
      { location: { lat: 37.785, lng: -122.445 }, weight: 2 },
      { lat: 37.785, lng: -122.443 },
      { location: { lat: 37.785, lng: -122.441 }, weight: 0.5 },
      { lat: 37.785, lng: -122.439 },
      { location: { lat: 37.785, lng: -122.437 }, weight: 2 },
      { location: { lat: 37.785, lng: -122.435 }, weight: 3 },
    ]
    </script>
    
    <template>
      <GoogleMap
        api-key="YOUR_GOOGLE_MAPS_API_KEY"
        version="3.64"
        :libraries="['visualization']"
        style="width: 100%; height: 500px"
        :center="sanFrancisco"
        :zoom="13"
      >
        <HeatmapLayer :options="{ data: heatmapData }" />
      </GoogleMap>
    </template>
  6. Load the Google Maps API script externally using apiPromise

    develop

    If your application already loads the Google Maps API (e.g., via @googlemaps/js-api-loader or in a larger host application), you can prevent vue3-google-map from loading its own script by passing a promise to the api-promise prop. This promise must resolve to the window.google object.

    This is recommended when you need to ensure specific libraries (like places) are loaded or when you want to control the loading lifecycle globally.

    <script setup>
    import { GoogleMap, Marker } from 'vue3-google-map';
    import { setOptions, importLibrary } from '@googlemaps/js-api-loader';
    
    setOptions({
      key: YOUR_GOOGLE_MAPS_API_KEY,
      v: 'weekly',
    });
    
    // Create a promise that resolves to the google object
    const apiPromise = Promise.all([
      importLibrary('maps'),
      importLibrary('places'),
    ]).then(() => window.google);
    
    const center = { lat: 40.689247, lng: -74.044502 };
    </script>
    
    <template>
      <GoogleMap
        :api-promise="apiPromise"
        style="width: 100%; height: 500px"
        :center="center"
        :zoom="15"
      >
        <Marker :options="{ position: center }" />
      </GoogleMap>
    </template>
  7. Use the Rectangle component to draw shapes

    develop

    The Rectangle component allows you to draw simple rectangles on a GoogleMap. To use it, pass a configuration object to the :options prop. This object follows the RectangleOptions schema from the Google Maps JavaScript API.

    Key configuration properties include:

    • bounds: An object defining the rectangle's area using north, south, east, and west coordinates.
    • strokeColor: The color of the rectangle's border.
    • strokeOpacity: The opacity of the border.
    • strokeWeight: The thickness of the border.
    • fillColor: The color of the rectangle's interior.
    • fillOpacity: The opacity of the interior.
    <script setup>
    import { GoogleMap, Rectangle } from 'vue3-google-map'
    
    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,
      },
    }
    </script>
    
    <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>
  8. Nest InfoWindow with Marker or AdvancedMarker

    develop

    To display an info window when a marker is clicked, nest the InfoWindow component inside either the Marker or AdvancedMarker component.

    With Marker

    Nesting InfoWindow inside a Marker allows the popup to be associated with that specific marker's position.

    With AdvancedMarker

    Nesting InfoWindow inside an AdvancedMarker works similarly. You can also use the #content template on the AdvancedMarker to customize the marker's appearance itself while keeping the InfoWindow for the popup content.

    <script setup>
    import { GoogleMap, Marker, InfoWindow } from 'vue3-google-map'
    
    const center = { lat: -25.363, lng: 131.044 }
    </script>
    
    <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="content">
              <h1>Uluru</h1>
              <p>Content goes here...</p>
            </div>
          </InfoWindow>
        </Marker>
      </GoogleMap>
    </template>
  9. Use the Marker component

    develop

    The Marker component is used to draw markers, drop pins, or display custom icons on a map.

    ::: warning DEPRECATED The Marker component is deprecated as of February 2024. For new projects, please use the AdvancedMarker component instead, as the legacy google.maps.Marker API will be removed in a future version. :::

    <script setup>
    import { GoogleMap, Marker } from 'vue3-google-map'
    
    const center = { lat: 40.689247, lng: -74.044502 }
    const markerOptions = { position: center, label: 'L', title: 'LADY LIBERTY' }
    </script>
    
    <template>
      <GoogleMap
        api-key="YOUR_GOOGLE_MAPS_API_KEY"
        style="width: 100%; height: 500px"
        :center="center"
        :zoom="15"
      >
        <Marker :options="markerOptions" />
      </GoogleMap>
    </template>
  10. Create your first map with GoogleMap

    develop

    To render a map, use the GoogleMap component. It requires a valid Google Maps API key and styling (such as width and height). You can configure the map using standard MapOptions.

    To add features like markers or shapes, pass subcomponents (e.g., Marker, Polyline, Polygon, Rectangle, Circle, or CustomControl) into the default slot of the GoogleMap component.

    The GoogleMap component also emits standard Google Maps JavaScript API events, which can be handled using the @event_name syntax.

    <script setup>
    import { GoogleMap, Marker } from 'vue3-google-map'
    
    const center = { lat: 40.689247, lng: -74.044502 }
    </script>
    
    <template>
      <GoogleMap
        api-key="YOUR_GOOGLE_MAPS_API_KEY"
        style="width: 100%; height: 500px"
        :center="center"
        :zoom="15"
      >
        <Marker :options="{ position: center }" />
      </GoogleMap>
    </template>
  11. Apply custom styles to GoogleMap

    develop

    To apply custom visual styles, pass a style configuration object to the styles prop of the GoogleMap component. The format of this object follows the Google Maps JavaScript API MapOptions.styles specification.

    Warning: If you specify a value for the theme prop, it will override any custom styles provided via the styles prop.

    <template>
      <!-- Use the styles prop for custom Google Maps JSON style objects -->
      <GoogleMap 
        api-key="YOUR_GOOGLE_MAPS_API_KEY" 
        :center="center" 
        :zoom="4" 
        :styles="customStyles" 
      />
    </template>
    
    <script>
    import { defineComponent } from 'vue'
    import { GoogleMap } from 'vue3-google-map'
    
    export default defineComponent({
      components: { GoogleMap },
      setup() {
        const center = { lat: 39.50024, lng: -98.350891 }
        const customStyles = [
          {
            "featureType": "water",
            "elementType": "geometry",
            "stylers": [{ "color": "#ffffcc" }]
          }
        ]
        return { center, customStyles }
      },
    })
    </script>
  12. Load the Google Maps API script externally using api-promise

    develop

    By default, GoogleMap handles script loading via the api-key prop. If you need to manage the loading yourself (e.g., to integrate with an existing Google Maps setup or to load specific libraries in parallel), use the api-promise prop. This prop accepts a Promise that resolves to the Google Maps API global google object.

    <script setup>
    import { GoogleMap, AdvancedMarker } from 'vue3-google-map';
    import { setOptions, importLibrary } from '@googlemaps/js-api-loader';
    
    // 1. Configure the loader (once per app)
    setOptions({
      key: 'YOUR_GOOGLE_MAPS_API_KEY',
      v: 'weekly',
    });
    
    // 2. Create a promise that resolves to the google object
    const apiPromise = Promise.all([
      importLibrary('maps'),
      importLibrary('places'),
      importLibrary('marker'),
    ]).then(() => {
      if (window.google) {
        return window.google;
      }
      throw new Error('Google Maps API not loaded');
    });
    
    const center = { lat: 40.689247, lng: -74.044502 };
    </script>
    
    <template>
      <!-- 3. Pass the promise to the component -->
      <GoogleMap
        :api-promise="apiPromise"
        mapId="DEMO_MAP_ID"
        style="width: 100%; height: 500px"
        :center="center"
        :zoom="15"
      >
        <AdvancedMarker :options="{ position: center }" />
      </GoogleMap>
    </template>