Incorporating Google Maps into vue.js

Trying to set up a Google map in a vue.js project has been challenging. I have included the script like this:

<script src="https://maps.googleapis.com/maps/api/js?key=MY_API_KEY&callback=initMap" async defer></script>

The issue arises with my .vue files looking like this:

<template>
  ...
</template>

<script>
  ...
</script>

I am unable to add more than one script tag in my vue file, and although I could display the map by placing code in the index.html, I would prefer not to mix JS in that file. Additionally, I am unable to direct the script callback to a vue method.

Does anyone have any suggestions on how to incorporate the map using a .vue file? I did try using vue2-google-maps but I wish to utilize the original Google map.

A fiddle I created demonstrates some success without a callback in the script tag: https://jsfiddle.net/okubdoqa/, however, I am facing difficulties making it work. Thank you.

Answer №1

I recommend utilizing npm google-maps instead of including a script directly in index.html. This way, you can avoid loading the Google Maps API on every page and make use of Webpack efficiently. You can easily install it using npm install google-maps

import GoogleMapsLoader from 'google-maps'

mounted: function () {
  GoogleMapsLoader.load(function(google) {
    let map = new google.maps.Map(document.getElementById('map'), {
      zoom: 15,
      center: position
    })
  })
}

Answer №2

Implementing this functionality without relying on a library can be a bit tricky, but it is possible. Alternatively, you could import the library and integrate it into your components to simplify the process.

Instead of using the defer & async attributes in the <script> tag, load the library in your index.html:

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

Once the library is loaded, you can access the global google object in your component and initialize it with an element. Here's an example setup using Vue.js:

<template>
  <div class="hello">
    <h1>{{ msg }}</h1>

    <div id="myMap"></div>
  </div>
</template>

<script>
export default {
  name: 'hello',
  data () {
    return {
      msg: 'Welcome to Your Vue.js App'
    }},
  mounted: function() {
        console.log("map: ", google.maps)
            this.map = new google.maps.Map(document.getElementById('myMap'), {
            center: {lat:61.180059, lng: -149.822075},
            scrollwheel: false,
            zoom: 4
            })
  }

}
</script>
<style scoped>
    #myMap {
    height:300px;
    width: 100%;
   }
</style>

Answer №3

While investigating a different issue, I stumbled upon a solution that doesn't require modifying the index.html file.

I encountered a similar dilemma when I needed to use two Google API keys for separate environments. Hard-coding them into index.html wasn't ideal, so I came up with an alternative approach:

main.js

export const loadedGoogleMapsAPI = new Promise( (resolve,reject) => {

      window['GoogleMapsInit'] = resolve;

      let GMap = document.createElement('script');

      GMap.setAttribute('src',
     `https://maps.googleapis.com/maps/api/js?key=${process.env.GOOGLE_API_KEY}&callback=GoogleMapsInit&region=IN`);

      document.body.appendChild(GMap); 
});

MapElem.vue

<template>
   <div id="map"></div>
</template>

<script>
   import {loadedGoogleMapsAPI} from '@/main'

   export default {
     name: 'MapEl',
     mounted(){  
       loadedGoogleMapsAPI.then(()=>{
         this.initMap()
       });
     },
    methods:{
     initMap(){
        console.log(google.maps); //You can now access google maps object here
        new google.maps.Map(document.getElementById('map'), {
          // You configuration goes here
        })
     }
    }
</script>

This method involves writing a Promise in main.js that will resolve to the callback triggered by the dynamically appended Google script. Once the Promise resolves, you can access the map object in your component.

Answer №4

If you're looking for a way to encapsulate code within a Component using the async loader $Scriptjs, there's an alternative method you can try.

Get started by installing it through npm

npm install scriptjs

Next, import it into your component like so:

import $Scriptjs from 'scriptjs'

Then, in the mounted hook of your component (assuming you have a method named initMap), load the script:


...
mounted () {
  $Scriptjs('https://maps.googleapis.com/maps/api/js?key={YOUR_KEY}', () => {
      this.initMap()
}
...

Answer №5

After integrating the Google Maps callback function, here is the initial Vue part.

function initializeMap(){
var app = new Vue({
el:"#app",
data:{
name:"Niklesh Raut",
map:"",
mapOptions:{}
},
mounted(){
this.initializeMap();
},
methods:{
initializeMap: function(){
this.mapOptions = {
center: new google.maps.LatLng(21.139808079490507, 79.07690763473511),
zoom: 10,
mapTypeId: 'roadmap'
}
this.map = new google.maps.Map(document.getElementById("map"), this.mapOptions);
}
}
});
}
.wrapper {
    display: flex;
    width: 100%;
    align-items: stretch;
}
#content {
    width: 100%;
    /*padding: 20px;*/
    min-height: 100vh;
    transition: all 0.3s;
}
.map{
    height: 100%;
    width:100%;
}
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<script async defer src="https://maps.googleapis.com/maps/api/js?key=AIzaSyDUFmbwJMBHU_paeMfVO7oqPC1IJEtbJUU&callback=initializeMap"></script>
</head>

<div id="app" class="wrapper">
<div id="content">
Name : {{name}}
<div id="map" class="map"></div>
</div>
</div>

Jsfiddle Link

Answer №6

One of the easiest ways to incorporate Google Maps into a Vue project is by utilizing npm packages. For this purpose, you can make use of vue-google-maps.

npm install vue2-google-maps

Then, follow these steps:

import Vue from 'vue'
import * as VueGoogleMaps from 'vue2-google-maps'

Vue.use(VueGoogleMaps, {
  load: {
    key: 'YOUR_API_TOKEN',
  },
})

You can easily embed the following code snippet:

<GmapMap
  :center="{lat:10, lng:10}"
  :zoom="7"
  map-type-id="terrain"
  style="width: 500px; height: 300px"
>


</GmapMap>

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Tips for successfully retrieving a boolean value from an ASP.Net JavaScript AJAX request using a C# method

Query: Is there a way to call a C# function from JavaScript code on an .aspx webpage to get authentication results based on a username and password? Here is the JavaScript AJAX POST request I am currently using: $.ajax({ type: "POST", ...

What is the best way to update all React components with a context without using a provider?

Considering this straightforward custom hook import React, { createContext, useContext } from 'react'; const context = { __prefs: JSON.parse(localStorage.getItem('localPreferences') || null) || {} , get(key, defaultValue = null) ...

Having trouble with React button conditional rendering not functioning properly

Currently, I am working on a cart application and facing an issue. The problem is that the button is not getting disabled when the quantity reaches zero. Instead, it continues to show the 'add to cart' button even when no items are left in stock. ...

Various perspectives within a state

I am facing an issue with my articledetail state when navigating to it: $state.go('articledetail', { 'article': article.itemNumber }); Within the articleDetail.html file, I want to display all subviews simultaneously: <div cla ...

Download function in Express.JS failing to retrieve file

I have been working on a Node.JS server using Express to generate and download PDFs based on user input. Previously, I used the <form action=""> method to call my API, but switched to Axios due to Netlify not supporting NuxtAPI. The program ...

What web browsers encounter issues when storing XMLHTTPRequest responses in the cache?

Are there any potential issues with caching XMLHttpRequest responses in current browsers that I should take into consideration? I want to use XMLHttpRequest queries on each page to dynamically load relevant content (such as JSON) or behavior (like eval()e ...

Moment JS initialization and the utc() function

I am trying to comprehend the way Moment JS initializes its moment object. For instance, let's say I want to create a moment for the date and time: April 1, 2000, 3:25:00 AM with a UTC offset of +8 hours from UTC/GMT. To represent this in JavaScript ...

Personalizing buttons on a carousel in React-bootstrap

I am facing an issue with my carousel and buttons placement. The buttons need to be outside of the carousel, but I'm unsure how to connect them effectively. React-Bootstrap's activeIndex option was suggested, but since my carousel is not cyclic l ...

Saving JSON data as a file on server

Currently, I am running a localhost website on my Raspberry Pi using Apache and I am seeking advice on how to export a JSON string to a file on the Raspberry Pi itself. While I do know how to export a file, I am unsure of how to send it to the Raspberry Pi ...

What is the proper way to insert a JavaScript file into jQuery code using the script tag?

I need help integrating a JS file into jQuery scripts to manipulate data retrieved from a database using $.ajax. I want to perform actions without refreshing the page. For example: $.ajax({ type: 'POST', url: "content.php", data: {vals: " ...

How can one acquire additional values that align with a specific value?

I have a JSON file containing a large amount of data. Here is an excerpt from the JSON file: { "thefirst": { "one": { "color1": "red", "color2": "blue" }, "two": { "color3": "green", "color4": "purple" } ...

Node.js encounters a failure when trying to set headers after they have already been sent in an HTTP request

Attempting to request a server using https/http and display the result on a web page. The script works fine on a server but fails when trying to return the result with a get request. var express = require('express'); var app = express(); var por ...

if the current value in the field surpasses the specified value in JavaScript

Looking to incorporate an additional condition into a JavaScript function initial condition if (content.length==elmnt.maxLength) new condition if (content.length==elmnt.maxLength && current form field value > 1400) How can I properly implement the ...

How come Nuxtjs doesn't refresh the template when the data is modified?

Within my Nuxt component, I have included the following HTML in the template: <div class="slider" id="slider" ref="slider" :style="'transform: transitionX(-' + sliderPosition + '%)'"> Addit ...

Is there a more concise method to achieve this in JavaScript? (details below)

I am developing a calculator and implementing eventListeners to the number buttons using JavaScript. Here is the code snippet: document.addEventListener('click', e =>{ if (e.target.matches('#num1')){ const x = document.cr ...

What could be causing the inability to 'GET' a page on an express app?

As a beginner in web app development, I've been self-teaching Node Express. While I've had success running simple express apps on Cloud9 environments, I'm facing difficulties getting them to work with VS Code. The server starts up fine, but ...

Accessing a Parent Object's Method Within a ForEach Loop

While this question leans towards a JavaScript issue rather than Angular, the context remains within Angular. The problem arises when attempting to call the doSomething method from lodash's ._forEach, which creates its own scope causing an inability t ...

Ensuring the "X" Button of a jQueryUI Dialog Remains Visible on the Screen

Take a look at this CodePen example: https://codepen.io/ChrisVomRhein/pen/yzBwaZ Upon clicking the button, a dialog containing a large amount of text opens. The following code snippet is responsible for positioning the dialog relative to the button: $( " ...

Increasing the value of an external variable in MySQL Query through NodeJS

Currently, I am in the process of developing an API using NodeJS and MySQL. The main function of this API is to create new entries by executing queries one by one. In order to keep track of the successful execution of these queries, I have introduced a va ...

Updating switch data on click using Vuejs: A step-by-step guide

Could someone please explain to me how to swap two different sets of data when clicked? For instance, let's say we have the following data: data() { return { data_one: [ { name: "Simo", ...