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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.07 00:20:46