Vue.js中在模态框内嵌入Google地图无法正常显示的问题求助
Vue.js中在模态框内嵌入Google地图无法正常显示的问题求助
各位大佬好,我现在碰到个头疼的问题:想在Vue项目的Bootstrap模态框里嵌入Google地图,但地图始终没法正常显示。我把相关代码贴出来,感觉问题应该出在脚本逻辑这块,麻烦帮忙看看哪里错了😭
1. Blade模板里的Google Maps脚本引入
<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCtTed7y_ePqg1QoDMHOyu01FtP_Ot-mDU" async defer></script>
2. Vue组件中的模态框结构
<div class="modal fade" id="modal-location" aria-labelledby="modal-locationLabel" aria-hidden="true"> <div class="modal-dialog"> <div class="modal-content"> <div class="modal-header"> ... </div> <div class="modal-body"> <form> <div v-show="!showofflocation"> <div id="map" style="height:300px"></div> <input type="hidden" v-model="selectedLat" id="latitude"> <input type="hidden" v-model="selectedLng" id="longitude"> </div> ... </form> </div> </div> </div> </div>
3. Vue的<script setup>脚本部分
<script setup> /* global google */ ... import { ref, computed, onMounted, defineProps, nextTick } from 'vue'; const selectedLat = ref(null); const selectedLng = ref(null); const initMap = () => { const mapElement = document.getElementById("map"); if (!mapElement) { console.error("Map div not found!"); return; } const defaultLocation = { lat: 5.6037, lng: -0.1870 }; // Accra const map = new google.maps.Map(mapElement, { center: defaultLocation, zoom: 12, }); const marker = new google.maps.Marker({ position: defaultLocation, map, draggable: true, }); google.maps.event.addListener(map, "click", (event) => { marker.setPosition(event.latLng); selectedLat.value = event.latLng.lat(); selectedLng.value = event.latLng.lng(); }); }; $('#modal-location').on('shown.bs.modal', () => { initMap(); }); onMounted(async () => { resetFormData(); fetchTopCategories(); const lat = localStorage.getItem('loction_current_lat'); const long = localStorage.getItem('loction_current_long'); await nextTick(); initMap(); }); </script>
我自己排查的几个可能问题点(供参考)
- 地图元素可见性问题:模态框默认是隐藏的,
onMounted阶段调用initMap时,#map元素可能还处于不可见状态,Google地图在隐藏元素上初始化会无法正确计算尺寸,导致显示异常。 - 重复初始化:
onMounted和模态框shown.bs.modal事件都调用了initMap,可能导致地图实例冲突或者重复创建。 - Google API加载时机:脚本是
async defer加载的,可能在initMap执行时google对象还没完全初始化。
尝试的修复方案建议
我调整了代码逻辑,你可以试试:
<script setup> /* global google */ ... import { ref, computed, onMounted, defineProps, nextTick } from 'vue'; const selectedLat = ref(null); const selectedLng = ref(null); const initMap = () => { // 先检查Google Maps API是否加载完成 if (typeof google === 'undefined' || !google.maps) { console.error("Google Maps API 还未加载完成!"); return; } const mapElement = document.getElementById("map"); if (!mapElement) { console.error("Map div not found!"); return; } // 确保地图元素是可见的 if (mapElement.offsetParent === null) { console.error("Map元素当前处于隐藏状态!"); return; } const defaultLocation = { lat: 5.6037, lng: -0.1870 }; // Accra const map = new google.maps.Map(mapElement, { center: defaultLocation, zoom: 12, }); // 初始化后触发resize事件,让地图重新计算尺寸 google.maps.event.trigger(map, 'resize'); // 重新设置地图中心,防止偏移 map.setCenter(defaultLocation); const marker = new google.maps.Marker({ position: defaultLocation, map, draggable: true, }); google.maps.event.addListener(map, "click", (event) => { marker.setPosition(event.latLng); selectedLat.value = event.latLng.lat(); selectedLng.value = event.latLng.lng(); }); }; // 只在模态框完全显示后初始化地图 $('#modal-location').on('shown.bs.modal', () => { nextTick(() => { initMap(); }); }); onMounted(async () => { resetFormData(); fetchTopCategories(); const lat = localStorage.getItem('loction_current_lat'); const long = localStorage.getItem('loction_current_long'); // 移除这里的initMap调用,避免在隐藏状态下初始化 }); </script>
核心调整点:
- 移除
onMounted中的initMap调用,只在模态框shown事件中初始化 - 增加Google API加载完成的检查
- 地图初始化后触发
resize事件并重新设置中心,解决隐藏元素初始化导致的尺寸异常
内容来源于stack exchange
相关产品推荐
相关产品推荐

