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
相关产品推荐
相关产品推荐

