Vue.js中Google Map加载异常:需Ctrl+F5刷新才可正常加载
解决Vue mounted钩子中Google Map加载失败的问题
这个问题我之前也碰到过,核心原因很明确:你给Google Maps的脚本加了async defer属性,这会让脚本异步加载,而Vue的mounted钩子会在DOM挂载完成后立即执行,这时候Google Maps的脚本可能还没加载完毕,自然就找不到google这个全局变量了。强制刷新时脚本已经被浏览器缓存,加载速度变快,刚好赶在mounted执行前完成,所以能正常工作。
下面给你几个靠谱的解决方案,按推荐程度排序:
方案一:利用Google Maps官方的回调参数(推荐)
这是Google官方推荐的异步加载方式,直接在脚本URL里指定callback参数,当脚本加载完成后会自动调用这个回调函数,我们把地图初始化的逻辑放到这个回调里就行:
<div id="app"> <div id="map"></div> </div> <script src="https://maps.googleapis.com/maps/api/js?key=****&callback=initMap" async defer></script> <script> let app; function initMap() { app = new Vue({ el:'#app', data() { return { map: null } }, mounted() { this.map = new google.maps.Map(document.getElementById('map'), { center: {lat: -34.397, lng: 150.644}, zoom: 8 }); } }); } </script>
如果你的Vue实例需要提前创建,也可以让回调触发Vue内部的方法:
<div id="app"> <div id="map"></div> </div> <script> const app = new Vue({ el:'#app', data() { return { map: null } }, methods: { initGoogleMap() { this.map = new google.maps.Map(document.getElementById('map'), { center: {lat: -34.397, lng: 150.644}, zoom: 8 }); } } }); // Google Maps脚本加载完成后触发这个函数 function googleMapsReady() { app.initGoogleMap(); } </script> <script src="https://maps.googleapis.com/maps/api/js?key=****&callback=googleMapsReady" async defer></script>
方案二:在mounted里轮询检查google变量
如果不想修改脚本标签的回调,可以在mounted里设置一个定时器,每隔一段时间检查google是否可用,直到可用再初始化地图:
new Vue({ el:'#app', data() { return { map: null, checkTimer: null } }, mounted() { this.checkTimer = setInterval(() => { // 检查google全局变量是否存在 if (typeof google !== 'undefined') { clearInterval(this.checkTimer); this.map = new google.maps.Map(document.getElementById('map'), { center: {lat: -34.397, lng: 150.644}, zoom: 8 }); } }, 100); // 每100ms检查一次 }, beforeDestroy() { // 组件销毁前清理定时器,避免内存泄漏 if (this.checkTimer) clearInterval(this.checkTimer); } });
方案三:动态加载Google Maps脚本
在Vue的mounted钩子中动态创建脚本标签,监听其onload事件,等脚本加载完成后再初始化地图:
new Vue({ el:'#app', data() { return { map: null } }, mounted() { const script = document.createElement('script'); script.src = 'https://maps.googleapis.com/maps/api/js?key=****'; script.onload = () => { this.map = new google.maps.Map(document.getElementById('map'), { center: {lat: -34.397, lng: 150.644}, zoom: 8 }); }; // 把脚本添加到页面中 document.body.appendChild(script); } });
总的来说,方案一是最稳妥的,符合Google官方的设计规范,也能完美避免生命周期和脚本加载时机不匹配的问题。
内容的提问来源于stack exchange,提问作者Rahul Reghunath
相关产品推荐
相关产品推荐

