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

Vue3中如何在Google Maps信息窗的HTML字符串里引用函数?

解决Vue3中Google Maps信息窗按钮调用组件内函数的问题

你遇到的问题核心在于:Google Maps信息窗的自定义HTML是直接插入到DOM中的,其中onclick="testFx()"会在全局作用域查找testFx函数,但Vue3 <script setup> 里定义的函数是模块私有作用域,不会暴露到全局window对象上,因此抛出testFx is not defined的错误。

以下是推荐的规范解决方案:

方法:利用InfoWindow的domready事件绑定事件

Google Maps的InfoWindow提供了domready事件,会在信息窗DOM渲染完成后触发。我们可以在这个事件回调中获取按钮元素,直接绑定组件内的函数,无需依赖全局作用域。

修改后的完整代码:

<script setup>
/* eslint-disable no-undef */
import { ref, onMounted, onUnmounted } from 'vue'
import { useMapStore } from '../pinia/map'
import { Loader } from '@googlemaps/js-api-loader'

const mapStore = useMapStore()
const GOOGLE_MAPS_API_KEY = import.meta.env.VITE_GAPI
const loader = new Loader({
  apiKey: GOOGLE_MAPS_API_KEY,
  version: 'beta',
  libraries: ['marker']
})

const mapDiv = ref(null)
let map = mapStore.map
let infoWindow = null // 声明全局变量,方便后续清理

const initMap = async () => {
  await loader.load()

  map = new google.maps.Map(mapDiv.value, {
    center: { lat: 40, lng: -80 },
    zoom: 4,
    maxZoom: 19,
    minZoom: 3
  })

  const marker = new google.maps.Marker({
    position: { lat: 40, lng: -80 },
    map: map,
    title: 'My Marker'
  })

  // 去掉onclick属性,只保留基础HTML结构
  const infoWindowContent = '<div><h3>My Marker Info Window</h3><button id="info-window-btn">WORK</button></div>'
  infoWindow = new google.maps.InfoWindow({
    content: infoWindowContent
  })

  // 监听domready事件,绑定按钮点击
  infoWindow.addListener('domready', () => {
    const btn = document.getElementById('info-window-btn')
    if (btn) {
      btn.addEventListener('click', testFx)
    }
  })

  marker.addListener('click', () => {
    infoWindow.open(map, marker)
  })
}

onMounted(async () => {
  await initMap()
})

const testFx = () => {
  console.log('something worked')
}

// 组件卸载时清理资源,避免内存泄漏
onUnmounted(() => {
  if (infoWindow) {
    infoWindow.close()
    infoWindow = null
  }
})
</script>

<template>
  <div style="overflow-y: hidden">
    <div ref="mapDiv" style="background-color: #4CAF50; width: 100%; height: 90vh"></div>
  </div>
</template>

可选快捷方法(不推荐生产环境使用)

如果只是临时测试,可以将组件内的函数临时挂载到window对象上,但要注意组件卸载时清理,避免全局污染:

// 在onMounted中添加
onMounted(async () => {
  await initMap()
  window.testFx = testFx
})

// 在onUnmounted中清理
onUnmounted(() => {
  delete window.testFx
  if (infoWindow) {
    infoWindow.close()
    infoWindow = null
  }
})

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 05:22:28