跳转至

Nuxt 4 模式

在构建或调试使用 SSR、混合渲染、路由规则或页面级数据获取的 Nuxt 4 应用时使用。

激活时机

  • 服务器 HTML 与客户端状态之间的水合不一致
  • 路由级别的渲染决策,例如预渲染、SWR、ISR 或仅客户端区域
  • 与延迟加载、延迟水合或负载大小相关的性能工作
  • 使用 useFetch、useAsyncData 或 $fetch 进行页面或组件的数据获取
  • 与路由参数、中间件或 SSR/客户端差异相关的 Nuxt 路由问题

水合安全性

  • 保持首次渲染的确定性。不要在 SSR 渲染的模板状态中直接使用 Date.now()、Math.random()、仅浏览器可用的 API 或存储读取。
  • 如果服务器无法生成相同的标记,请将仅浏览器的逻辑移到 onMounted()、import.meta.client、ClientOnly 或 .client.vue 组件中。
  • 使用 Nuxt 的 useRoute() 组合式函数,而不是 vue-router 的。
  • 不要使用 route.fullPath 来驱动 SSR 渲染的标记。URL 片段仅存在于客户端,可能导致水合不一致。
  • 将 ssr: false 视为真正仅浏览器区域的逃生舱口,而不是不一致问题的默认修复手段。

数据获取

  • 在页面和组件中优先使用 await useFetch() 进行 SSR 安全的 API 读取。它会将服务器上获取的数据传输到 Nuxt 负载中,避免水合时的第二次请求。
  • 当获取器不是简单的 $fetch() 调用、需要自定义键,或需要组合多个异步源时,使用 useAsyncData()。
  • 为 useAsyncData() 提供稳定的键,以实现缓存复用和可预测的刷新行为。
  • 保持 useAsyncData() 处理器无副作用,因为它可能在 SSR 和水合期间执行。
  • 将 $fetch() 用于用户触发的写入或仅客户端操作,而不要用于应从 SSR 水合的顶层页面数据。
  • 对于不应阻塞导航的非关键数据,使用 lazy: true、useLazyFetch() 或 useLazyAsyncData(),并在 UI 中处理 status === 'pending'。
  • 仅对 SEO 或首次绘制不需要的数据使用 server: false。
  • 使用 pick 减小负载大小,并在不需要深层响应式时优先使用更浅的负载。
const route = useRoute()

const { data: article, status, error, refresh } = await useAsyncData(
  () => `article:${route.params.slug}`,
  () => $fetch(`/api/articles/${route.params.slug}`),
)

const { data: comments } = await useFetch(`/api/articles/${route.params.slug}/comments`, {
  lazy: true,
  server: false,
})

路由规则

对于渲染和缓存策略,优先使用 nuxt.config.ts 中的 routeRules:

export default defineNuxtConfig({
  routeRules: {
    '/': { prerender: true },
    '/products/**': { swr: 3600 },
    '/blog/**': { isr: true },
    '/admin/**': { ssr: false },
    '/api/**': { cache: { maxAge: 60 * 60 } },
  },
})
  • prerender:构建时的静态 HTML
  • swr:提供缓存内容的同时在后台重新验证
  • isr:在支持的平台上进行增量静态再生成
  • ssr: false:客户端渲染路由
  • cache 或 redirect:Nitro 级别的响应行为

按路由分组而非全局选择路由规则。营销页面、目录、仪表盘和 API 通常需要不同的策略。

延迟加载与性能

  • Nuxt 已经按路由对页面进行代码分割。在将组件拆分作为微优化之前,先保持路由边界的合理性。
  • 使用 Lazy 前缀动态导入非关键组件。
  • 使用 v-if 条件渲染延迟组件,确保在 UI 真正需要之前不会加载代码块。
  • 对首屏以下或非关键的交互式 UI 使用延迟水合。
<template>
  <LazyRecommendations v-if="showRecommendations" />
  <LazyProductGallery hydrate-on-visible />
</template>
  • 对于自定义策略,使用带可见性或空闲策略的 defineLazyHydrationComponent()。
  • Nuxt 的延迟水合适用于单文件组件。向延迟水合组件传递新的 props 会立即触发水合。
  • 使用 NuxtLink 进行内部导航,以便 Nuxt 能够预取路由组件和生成的负载。

审查清单

  • 首次 SSR 渲染和水合后的客户端渲染生成相同的标记
  • 页面数据使用 useFetch 或 useAsyncData,而不是顶层的 $fetch
  • 非关键数据已延迟加载,并有明确的加载 UI
  • 路由规则与页面的 SEO 和新鲜度要求相匹配
  • 重量级交互式孤岛已延迟加载或延迟水合

本页原文 Markdown:在 AtomGit 查看·内容源自开源项目 ev/ECC