
关于
Nuxt 4 应用模式,涵盖水合安全、性能优化、路由规则、懒加载以及使用 useFetch 和 useAsyncData 的 SSR 安全数据获取
name: nuxt4-patterns description: Nuxt 4 应用模式,涵盖水合安全、性能、路由规则、懒加载以及使用 useFetch 和 useAsyncData 的 SSR 安全数据获取。 origin: ECC
Nuxt 4 模式
在构建或调试使用 SSR、混合渲染、路由规则或页面级数据获取的 Nuxt 4 应用时使用。
何时激活
- 服务端 HTML 和客户端状态之间的水合不匹配
- 路由级渲染决策,如 prerender、SWR、ISR 或仅客户端部分
- 围绕懒加载、延迟水合或 payload 大小的性能优化
- 使用
useFetch、useAsyncData或$fetch的页面或组件数据获取 - 与路由参数、中间件或 SSR/客户端差异相关的 Nuxt 路由问题
水合安全
- 保持首次渲染的确定性。不要将
Date.now()、Math.random()、仅浏览器 API 或存储读取直接放入 SSR 渲染的模板状态中。 - 当服务端无法生成相同标记时,将仅浏览器逻辑放在
onMounted()、import.meta.client、ClientOnly或.client.vue组件之后。 - 使用 Nuxt 的
useRoute()组合式函数,而不是vue-router中的。 - 不要使用
route.fullPath来驱动 SSR 渲染的标记。URL 片段是仅客户端的,可能导致水合不匹配。 - 将
ssr: false视为真正仅浏览器区域的逃生舱,而不是修复不匹配的默认方案。
数据获取
- 在页面和组件中优先使用
await useFetch()进行 SSR 安全的 API 读取。它将服务端获取的数据转发到 Nuxt payload 中,避免水合时的二次请求。 - 当 fetcher 不是简单的
$fetch()调用、需要自定义 key 或组合多个异步源时,使用useAsyncData()。 - 为
useAsyncData()提供稳定的 key 以实现缓存复用和可预测的刷新行为。 - 保持
useAsyncData()处理函数无副作用。它们可能在 SSR 和水合期间运行。 - 对用户触发的写操作或仅客户端操作使用
$fetch(),而不是应从 SSR 水合的顶层页面数据。 - 对非关键数据使用
lazy: true、useLazyFetch()或useLazyAsyncData(),这些数据不应阻塞导航。在 UI 中处理status === 'pending'。 - 仅对 SEO 或首次绘制不需要的数据使用
server: false。 - 使用
pick精简 payload 大小,当不需要深度响应性时优先使用浅层 payload。
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:构建时生成静态 HTMLswr:提供缓存内容并在后台重新验证isr:在支持的平台上进行增量静态再生ssr: false:客户端渲染路由cache或redirect:Nitro 级别的响应行为
按路由组选择路由规则,而不是全局设置。营销页面、目录、仪表板和 API 通常需要不同的策略。
懒加载与性能
- Nuxt 已按路由自动进行代码分割。在微优化组件分割之前,保持路由边界有意义。
- 使用
Lazy前缀动态导入非关键组件。 - 使用
v-if条件渲染懒组件,使 chunk 在 UI 实际需要时才加载。 - 对首屏以下或非关键交互 UI 使用延迟水合。
<template>
<LazyRecommendations v-if="showRecommendations" />
<LazyProductGallery hydrate-on-visible />
</template>
- 对于自定义策略,使用
defineLazyHydrationComponent()配合可见性或空闲策略。 - Nuxt 延迟水合适用于单文件组件。向延迟水合的组件传递新 props 会立即触发水合。
- 使用
NuxtLink进行内部导航,以便 Nuxt 可以预取路由组件和生成的 payload。
审查清单
- 首次 SSR 渲染和水合后的客户端渲染产生相同标记
- 页面数据使用
useFetch或useAsyncData,而不是顶层$fetch - 非关键数据是懒加载的且有明确的加载 UI
- 路由规则匹配页面的 SEO 和新鲜度要求
- 重型交互岛屿是懒加载或延迟水合的
兼容工具
Claude CodeCursor
标签
前端开发
