Nuxt3中如何在<ContentDoc />加载完成前显示加载动画?
解决Nuxt3中ContentDoc加载延迟问题
一、优化加载以减少延迟
1. 预渲染静态内容
如果你的站点是静态类型,执行nuxt generate命令预渲染页面。这会提前将ContentDoc对应的文档内容生成为静态HTML,首次加载时直接展示完整内容,消除延迟。
2. 启用服务器端渲染(SSR)
在nuxt.config.ts中启用SSR模式,让服务器提前获取并渲染ContentDoc的内容,客户端收到响应时已经包含完整页面:
export default defineNuxtConfig({ ssr: true })
3. 开启文档内容缓存
如果文档内容更新不频繁,在Nuxt配置中开启Content模块的缓存,减少重复请求和解析耗时:
export default defineNuxtConfig({ content: { cache: { maxAge: 60 * 60 * 24 // 缓存24小时 } } })
二、添加加载动画/占位符
如果延迟无法完全消除,可通过以下方式在加载期间展示提示:
方法1:监听Content加载状态
手动获取文档数据并监听加载状态,在加载完成前显示动画:
<script setup lang="ts"> definePageMeta({ layout: "blog", }); // 获取文档数据并监听加载状态 const { data, pending } = await useAsyncData('content-doc', () => queryContent().findOne()) </script> <template> <main> <!-- 加载动画 --> <div v-if="pending" class="loading"> <div class="spinner"></div> <p>加载中...</p> </div> <!-- 内容加载完成后展示 --> <ContentDoc v-else :value="data" /> </main> </template> <style scoped> .loading { display: flex; flex-direction: column; align-items: center; justify-content: center; min-height: 50vh; } .spinner { width: 40px; height: 40px; border: 4px solid #f3f3f3; border-top: 4px solid #3498db; border-radius: 50%; animation: spin 1s linear infinite; } @keyframes spin { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } } </style>
方法2:使用ClientOnly组件
针对客户端渲染的内容,用<ClientOnly>包裹并指定加载占位符:
<template> <main> <ClientOnly> <ContentDoc /> <template #fallback> <div class="loading"> <div class="spinner"></div> <p>加载中...</p> </div> </template> </ClientOnly> </main> </template> <!-- 样式同上 -->
方法3:布局中添加全局加载状态
在blog布局中监听路由切换状态,全局展示加载动画:
<template> <div> <navbar /> <div> <div v-if="pageLoading" class="page-loading"> <div class="spinner"></div> </div> <slot v-else /> </div> <footer /> </div> </template> <script setup lang="ts"> const pageLoading = useState('pageLoading', () => true) // 路由切换时更新加载状态 useRouter().beforeEach(() => { pageLoading.value = true }) useRouter().afterEach(() => { pageLoading.value = false }) </script> <style scoped> .page-loading { position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(255,255,255,0.9); display: flex; align-items: center; justify-content: center; z-index: 9999; } .spinner { width: 50px; height: 50px; border: 5px solid #eee; border-top: 5px solid #3498db; border-radius: 50%; animation: spin 1s linear infinite; } @keyframes spin { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } } </style>
内容的提问来源于stack exchange,提问作者nur_riyad
相关产品推荐
相关产品推荐

