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

Vue.js预加载器组件加载、页面跳转后不消失问题排查与解决

问题根因

document.onreadystatechange仅监听浏览器原生文档的全量加载状态,Vue单页应用的路由跳转是组件级别的局部重渲染,不会触发浏览器原生文档加载状态的变更,因此跳转后绑定的监听回调不会执行,isloaded始终为初始值false,预加载器会持续显示。

修复方案

首先删除原有mounted中绑定document.onreadystatechange的逻辑,根据预加载器的放置位置选择对应实现:

方案1:预加载器为全局公共组件(放置在App.vue根组件)

通过监听路由变化控制预加载器状态,路由开始跳转时显示预加载器,页面DOM渲染完成后自动隐藏:

<template>
  <div class="page-loader" v-if="!isloaded">
    <div class="cube"></div>
    <div class="cube"></div>
    <div class="cube"></div>
    <div class="cube"></div>
  </div> 
  <router-view />
</template>

<script>
export default {
  data() {
    return {
      isloaded: false
    }
  },
  mounted() {
    // 首次进入页面渲染完成后隐藏预加载器
    this.isloaded = true
  },
  watch: {
    $route() {
      // 路由触发跳转时显示预加载器
      this.isloaded = false
      // 等待DOM更新渲染完成后隐藏预加载器
      this.$nextTick(() => {
        this.isloaded = true
      })
    }
  }
}
</script>

如果页面首屏存在接口请求、大图加载等异步逻辑,不要直接在$nextTick中修改状态,需要等所有首屏异步资源加载完成后,再将isloaded设为true,避免预加载器提前消失出现页面空白。

方案2:预加载器为页面级组件(每个业务页面单独引入)

不需要额外监听路由,直接利用组件自身的生命周期控制状态即可,每次路由切换进入页面、组件重新挂载时都会触发逻辑:

<template>
  <div class="page-loader" v-if="!isloaded">
    <div class="cube"></div>
    <div class="cube"></div>
    <div class="cube"></div>
    <div class="cube"></div>
  </div> 
  <!-- 页面业务内容 -->
</template>

<script>
export default {
  data() {
    return {
      isloaded: false
    }
  },
  mounted() {
    // 组件挂载、DOM渲染完成后隐藏预加载器
    // 存在异步加载逻辑时,将该行移到异步请求的最终回调中执行
    this.isloaded = true
  }
}
</script>
注意事项
  • Vue单页应用场景下不要依赖原生document.readyState判断页面渲染状态,路由切换不会触发该状态变更
  • 原代码中data使用箭头函数的写法存在隐患,箭头函数不会绑定组件实例作为this,后续逻辑需要依赖组件实例时会出现异常,建议改成普通函数写法
  • 涉及异步资源加载的场景,务必等首屏所需的接口、图片等资源全部加载完成后再关闭预加载器

内容的提问来源于stack exchange,提问作者JT Simon

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 09:45:38