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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 19:06:26