Vue中使用nuxt-link时onreadystatechange失效问题排查
问题原因及解决方案
问题原因
Nuxt 基于 Vue 构建,采用客户端路由(SPA 模式),通过 nuxt-link 跳转页面时,并不会重新加载整个 HTML 文档,仅替换页面内的组件内容。你绑定的 document.readystatechange、window.load、DOMContentLoaded 这些事件,只会在页面首次加载(刷新)时触发一次——因为此时文档已经处于 complete 状态,后续客户端路由切换时,文档状态不会再发生变化,所以绑定的事件自然不会触发。
可行实现方式
根据你要检测「媒体及文件是否完全加载」的需求,分两种场景给出解决方案:
1. 检测当前组件内的媒体资源(图片、视频等)
直接给媒体元素绑定加载事件,或者通过 Vue 的 ref 监听元素的加载状态:
单张图片示例
<template> <img ref="targetImg" src="/static/test.jpg" alt="测试图片"> </template> <script> export default { mounted() { const img = this.$refs.targetImg // 先判断是否已经加载完成 if (img.complete) { console.log('图片已加载完成') this.handleMediaLoaded() } else { // 绑定加载完成事件 img.addEventListener('load', () => { console.log('图片加载完成') this.handleMediaLoaded() }) // 监听加载失败情况 img.addEventListener('error', () => { console.log('图片加载失败') }) } }, methods: { handleMediaLoaded() { // 资源加载完成后的逻辑 } } } </script>
多个媒体资源批量检测
如果页面内有多个图片、视频,可以用 Promise.all 统一监听所有资源的加载状态:
<template> <div> <img ref="media" src="/static/img1.jpg" alt="图1"> <img ref="media" src="/static/img2.jpg" alt="图2"> <video ref="media" src="/static/video.mp4" controls></video> </div> </template> <script> export default { mounted() { const mediaElements = [...this.$refs.media] const loadPromises = mediaElements.map(el => { return new Promise((resolve, reject) => { // 针对不同媒体类型判断是否已加载 const isLoaded = el.complete && (el.tagName !== 'VIDEO' || el.readyState >= 2) if (isLoaded) { resolve(el) } else { // 图片/音频用load事件,视频用canplaythrough(表示可流畅播放,即资源加载完成) const loadEvent = el.tagName === 'VIDEO' ? 'canplaythrough' : 'load' el.addEventListener(loadEvent, () => resolve(el)) el.addEventListener('error', () => reject(el)) } }) }) Promise.all(loadPromises) .then(() => { console.log('所有媒体资源加载完成') // 执行后续逻辑 }) .catch(failedEl => { console.log(`资源加载失败:${failedEl.src}`) }) } } </script>
2. 检测路由跳转后目标页面的资源
如果需要在跳转到新页面后,检测目标页面的媒体资源,将上述监听逻辑放在目标页面的 mounted 钩子中即可。因为客户端路由跳转时,目标页面的组件会重新挂载,mounted 钩子会执行,此时可以正常监听该页面内的资源加载状态。
额外说明
如果你的需求是等待页面所有资源(包括外部样式、脚本)加载完成,在 Nuxt 中可以使用:
- 目标页面的
mounted钩子:此时页面 DOM 已渲染完成,可直接操作元素; - 若使用 Nuxt 3,可结合
useRouter的路由守卫和资源监听逻辑。
内容的提问来源于stack exchange,提问作者Onie Kim
相关产品推荐
相关产品推荐

