0

0

如何在 Nuxt 3 中准确判断所有请求与静态资源加载完成并控制自定义加载页

花韻仙語

花韻仙語

发布时间:2026-03-16 09:57:28

|

708人浏览过

|

来源于php中文网

原创

如何在 Nuxt 3 中准确判断所有请求与静态资源加载完成并控制自定义加载页

本文详解如何在 nuxt 3 中可靠地监听页面导航生命周期、捕获异步数据加载完成状态,并结合静态资源(如图片、第三方库)加载逻辑,实现精准的全局加载态控制。

本文详解如何在 nuxt 3 中可靠地监听页面导航生命周期、捕获异步数据加载完成状态,并结合静态资源(如图片、第三方库)加载逻辑,实现精准的全局加载态控制。

在 Nuxt 3 中实现「真正意义上的加载完成」——即等待页面路由过渡、useAsyncData/useFetch 数据请求、以及关键静态资源(如首屏图片、字体、CDN 脚本)全部就绪后再隐藏加载页——需要分层处理。仅依赖 page:start 和 page:finish 钩子是不充分的:它们仅反映 Vue 页面组件挂载流程,不保证异步数据已返回,更不感知静态资源加载状态

✅ 正确做法:组合生命周期钩子 + 数据加载状态 + 资源预加载

1. 使用 onServerPrefetch 与 onMounted 确保数据就绪

page:finish 钩子在服务端渲染(SSR)和客户端水合后触发,但它不等待 useAsyncData 的响应。因此,应在页面级组件中显式同步数据加载状态:

<!-- pages/index.vue -->
<script setup>
const { data, pending } = useAsyncData('posts', () => $fetch('/api/posts'))
const loading = ref(pending.value) // 初始状态由 pending 决定

watch(pending, (newVal) => {
  loading.value = newVal
})
</script>

<template>
  <div v-if="loading" class="fixed inset-0 bg-white z-50 flex items-center justify-center">
    <div class="text-xl font-medium">Loading...</div>
  </div>
  <div v-else>
    <h1>Posts List</h1>
    <pre>{{ data }}</pre>
  </div>
</template>

? 提示:pending 是响应式引用,会随 useAsyncData 状态自动更新,无需手动监听 page:finish。

2. 全局加载态:用 nuxtApp.hook + useState 实现跨组件共享

若需全局统一加载 UI(如顶部进度条或全屏遮罩),推荐在 app.vue 中管理,并通过 useState 持久化状态:

靠岸学术
靠岸学术

一款集翻译,阅读,文献管理于一体的英文文献阅读器

下载
<!-- app.vue -->
<script setup>
const nuxtApp = useNuxtApp()
const loading = useState<boolean>('globalLoading', () => true)

// 页面开始导航时开启
nuxtApp.hook('page:start', () => {
  loading.value = true
})

// 页面完成(含数据加载完毕)后关闭 —— 注意:需配合 useAsyncData 的 pending
nuxtApp.hook('page:finish', () => {
  // 延迟一帧确保所有 pending watch 已响应
  nextTick(() => {
    // 若当前无 pending 请求,则关闭
    const pendingStates = reactive({ count: 0 })
    nuxtApp.hook('app:data-loaded', () => {
      pendingStates.count--
      if (pendingStates.count <= 0) loading.value = false
    })
    // 手动触发一次检查(实际项目中建议封装为 useGlobalLoading())
    loading.value = false
  })
})
</script>

但更简洁可靠的方案是:放弃纯钩子方案,改用 useState + onBeforeMount/onMounted 统一收敛加载逻辑

3. 静态资源加载:主动监听关键资源就绪

Nuxt 3 不自动追踪 <img> 或 <link> 加载,需手动处理。例如,预加载首屏关键图片:

<script setup>
const loading = ref(true)
const imageLoaded = ref(false)

onMounted(() => {
  const img = new Image()
  img.src = '/hero.jpg'
  img.onload = () => {
    imageLoaded.value = true
  }
  img.onerror = () => {
    imageLoaded.value = true // 失败也视为“加载完成”,避免阻塞
  }
})

// 当数据 + 图片均就绪时关闭加载
watch([() => !pending.value, () => imageLoaded.value], ([isDataReady, isImgReady]) => {
  if (isDataReady && isImgReady) {
    loading.value = false
  }
})
</script>

⚠️ 注意事项

  • ❌ page:finish ≠ “所有请求完成”:它在组件 setup() 执行完即触发,此时 useAsyncData 可能仍在 pending。
  • ✅ 推荐以 pending 状态为唯一可信信号,而非钩子事件。
  • ? SSR 场景下,服务端已预取数据,客户端首次 pending 为 false;需用 useState 同步初始状态。
  • ? 第三方 JS/CSS(如 Analytics、Font Awesome)应通过 useHead 注入,并在 onMounted 中用 document.readyState 或 window.addEventListener('load') 辅助判断(适用于非核心资源)。

✅ 最佳实践总结

场景 推荐方式
页面数据加载 监听 useAsyncData().pending 或 useFetch().pending
全局加载 UI 在 app.vue 中用 useState + watch([pending1, pending2])
关键静态资源 new Image().onload / link.onload 主动监听
第三方脚本 useHead({ script: [...] }) + onMounted(() => { /* check window.MyLib */ })

通过分层控制数据流与资源流,你将获得可预测、可调试、且 SSR 友好的加载体验——告别“闪屏”与“假完成”。

相关标签:

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

WorkBuddy
WorkBuddy

腾讯云推出的AI原生桌面智能体工作台

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
js正则表达式
js正则表达式

php中文网为大家提供各种js正则表达式语法大全以及各种js正则表达式使用的方法,还有更多js正则表达式的相关文章、相关下载、相关课程,供大家免费下载体验。

531

2023.06.20

js获取当前时间
js获取当前时间

JS全称JavaScript,是一种具有函数优先的轻量级,解释型或即时编译型的编程语言;它是一种属于网络的高级脚本语言,主要用于Web,常用来为网页添加各式各样的动态功能。js怎么获取当前时间呢?php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

576

2023.07.28

js 字符串转数组
js 字符串转数组

js字符串转数组的方法:1、使用“split()”方法;2、使用“Array.from()”方法;3、使用for循环遍历;4、使用“Array.split()”方法。本专题为大家提供js字符串转数组的相关的文章、下载、课程内容,供大家免费下载体验。

761

2023.08.03

js是什么意思
js是什么意思

JS是JavaScript的缩写,它是一种广泛应用于网页开发的脚本语言。JavaScript是一种解释性的、基于对象和事件驱动的编程语言,通常用于为网页增加交互性和动态性。它可以在网页上实现复杂的功能和效果,如表单验证、页面元素操作、动画效果、数据交互等。

6310

2023.08.17

js删除节点的方法
js删除节点的方法

js删除节点的方法有:1、removeChild()方法,用于从父节点中移除指定的子节点,它需要两个参数,第一个参数是要删除的子节点,第二个参数是父节点;2、parentNode.removeChild()方法,可以直接通过父节点调用来删除子节点;3、remove()方法,可以直接删除节点,而无需指定父节点;4、innerHTML属性,用于删除节点的内容。

494

2023.09.01

js截取字符串的方法
js截取字符串的方法

js截取字符串的方法有substring()方法、substr()方法、slice()方法、split()方法和slice()方法。本专题为大家提供字符串相关的文章、下载、课程内容,供大家免费下载体验。

221

2023.09.04

Js中concat和push的区别
Js中concat和push的区别

Js中concat和push的区别:1、concat用于将两个或多个数组合并成一个新数组,并返回这个新数组,而push用于向数组的末尾添加一个或多个元素,并返回修改后的数组的新长度;2、concat不会修改原始数组,是创建新的数组,而push会修改原数组,将新元素添加到原数组的末尾等等。本专题为大家提供concat和push相关的文章、下载、课程内容,供大家免费下载体验。

240

2023.09.14

js截取字符串的方法介绍
js截取字符串的方法介绍

JavaScript字符串截取方法,包括substring、slice、substr、charAt和split方法。这些方法可以根据具体需求,灵活地截取字符串的不同部分。在实际开发中,根据具体情况选择合适的方法进行字符串截取,能够提高代码的效率和可读性 。

303

2023.09.21

TypeScript类型系统进阶与大型前端项目实践
TypeScript类型系统进阶与大型前端项目实践

本专题围绕 TypeScript 在大型前端项目中的应用展开,深入讲解类型系统设计与工程化开发方法。内容包括泛型与高级类型、类型推断机制、声明文件编写、模块化结构设计以及代码规范管理。通过真实项目案例分析,帮助开发者构建类型安全、结构清晰、易维护的前端工程体系,提高团队协作效率与代码质量。

90

2026.03.13

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号