You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Vue中加载Google Map API报错:google未定义 求助

Fixing "ReferenceError: google is not defined" in Vue with Google Maps

Got it, let's break down why you're hitting this error and walk through solid fixes.

The Root Cause

Your current setup has two critical timing issues:

  1. Vue Lifecycle Order: Parent components run their mounted hook after all child components have already executed their created and mounted hooks. By the time you inject the Google Maps script in the parent's mounted, your child component has already tried (and failed) to access the google object.
  2. Asynchronous Script Loading: Adding a script tag dynamically is an async operation—you can't immediately use google right after appending the script, since it needs time to download and execute.

Solution 1: Load Script Early & Control Child Rendering

The most reliable approach is to load the Google Maps script in the parent's created hook, wrap the script load in a promise, and only render the child component once the script is fully loaded.

Parent Component Code

<template>
  <div class="map-container">
    <!-- Only render child when script is loaded -->
    <MapChild v-if="isMapScriptLoaded" />
  </div>
</template>

<script>
import MapChild from './MapChild.vue';

export default {
  components: { MapChild },
  data() {
    return {
      isMapScriptLoaded: false
    };
  },
  created() {
    this.loadGoogleMaps();
  },
  methods: {
    loadGoogleMaps() {
      // Avoid reloading if script is already loaded
      if (window.google) {
        this.isMapScriptLoaded = true;
        return;
      }

      const script = document.createElement('script');
      script.src = 'https://maps.googleapis.com/maps/api/js?key=YourActualAPIKey';
      script.async = true;
      script.defer = true;

      // Handle successful script load
      script.onload = () => {
        this.isMapScriptLoaded = true;
        console.log('Google Maps script loaded successfully');
      };

      // Handle load errors
      script.onerror = () => {
        console.error('Failed to load Google Maps script');
      };

      document.head.appendChild(script);
    }
  }
};
</script>

Child Component Code

Now your child can safely access google in its mounted hook:

<template>
  <div id="map" style="width: 100%; height: 400px;"></div>
</template>

<script>
export default {
  mounted() {
    // Initialize map - google is guaranteed to exist here
    const map = new window.google.maps.Map(document.getElementById('map'), {
      center: { lat: -34.397, lng: 150.644 },
      zoom: 8
    });
  }
};
</script>

Solution 2: Use Event Communication (Alternative)

If you prefer not to use v-if to control rendering, you can emit an event from the parent once the script loads, then have the child listen for that event to initialize the map.

Parent Component Adjustment

Update the onload handler to emit an event:

script.onload = () => {
  this.$emit('maps-loaded');
  console.log('Google Maps script loaded successfully');
};

Child Component Adjustment

Listen for the event and initialize the map when it fires:

<script>
export default {
  mounted() {
    // Listen for the parent's loaded event
    this.$parent.$on('maps-loaded', this.initMap);
  },
  beforeUnmount() {
    // Clean up the event listener to avoid memory leaks
    this.$parent.$off('maps-loaded', this.initMap);
  },
  methods: {
    initMap() {
      const map = new window.google.maps.Map(document.getElementById('map'), {
        center: { lat: -34.397, lng: 150.644 },
        zoom: 8
      });
    }
  }
};
</script>

Quick Fix (For Small Apps)

If you don't mind a slight hit to initial page load performance, you can load the script directly in your index.html file. This ensures the script starts loading before Vue even initializes:

<!-- Add this to your public/index.html <head> -->
<script src="https://maps.googleapis.com/maps/api/js?key=YourActualAPIKey" async defer></script>

Then in your child component, you can still add a quick check to make sure google is available before initializing:

mounted() {
  // Wait for the script to load if it's still pending
  const checkGoogle = setInterval(() => {
    if (window.google) {
      clearInterval(checkGoogle);
      this.initMap();
    }
  }, 100);
}

Key Notes

  • Always verify your API key is valid and that the Maps JavaScript API is enabled in your Google Cloud Console.
  • Avoid loading the script multiple times—check window.google first before injecting a new script tag.

内容的提问来源于stack exchange,提问作者Justin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 07:55:30