Install any skill in seconds. Free to start, no credit card required.
Get Started Free →ハイドレーション安全性、パフォーマンス、ルートルール、遅延ロード、useFetchとuseAsyncDataを使ったSSR安全なデータフェッチングのためのNuxt 4アプリパターン。
.claude/skills/affaan-m-nuxt4-patterns/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-17 | ✗→✓ | ▲ Improved | 3% | 0% |
| case-18 | ✗→✓ | ▲ Improved | 6% | 0% |
| case-10 | ✓→✗ | ▼ Worse | 4% | 0% |
| case-07 | ✓→✓ | = Same ✓ | 42% | 0% |
| case-02 | ✓→✓ | = Same ✓ | 40% | 0% |
在构建或调试具有 SSR、混合渲染、路由规则或页面级数据获取的 Nuxt 4 应用时使用。
useFetch、useAsyncData 或 $fetch 进行页面或组件数据获取Date.now()、Math.random()、仅限浏览器的 API 或存储读取直接放入 SSR 渲染的模板状态中。onMounted()、import.meta.client、ClientOnly 或 .client.vue 组件后面。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'。server: false。pick 修剪有效负载大小,并在不需要深层响应性时优先使用较浅的有效负载。tsconst 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 来定义渲染和缓存策略:
tsexport 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 通常需要不同的策略。
Lazy 前缀来动态导入非关键组件。v-if 有条件地渲染懒加载组件,以便在 UI 实际需要时才加载该代码块。vue<template> <LazyRecommendations v-if="showRecommendations" /> <LazyProductGallery hydrate-on-visible /> </template>
defineLazyHydrationComponent() 配合可见性或空闲策略。NuxtLink,以便 Nuxt 可以预取路由组件和生成的有效负载。useFetch 或 useAsyncData,而非顶层的 $fetch| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-07 | pass→pass | 9,880 | 6,766 | -32% | 1 | 1 | 0% | 1,709 | 2,429 | +42% | 0 | 0 | — |
case-01 | fail→fail | 18,482 | 15,177 | -18% | 1 | 1 | 0% | 3,304 | 3,987 | +21% | 0 | 0 | — |
case-02 | pass→pass | 12,413 | 10,135 | -18% | 1 | 1 | 0% | 2,133 | 2,985 | +40% | 0 | 0 | — |
case-03 | pass→pass | 9,682 | 6,571 | -32% | 1 | 1 | 0% | 1,543 | 2,312 | +50% | 0 | 0 | — |
case-04 | pass→pass | 14,096 | 10,079 | -28% | 1 | 1 | 0% | 2,381 | 2,876 | +21% | 0 | 0 | — |
case-05 | pass→pass | 14,502 | 11,444 | -21% | 1 | 1 | 0% | 2,368 | 3,292 | +39% | 0 | 0 | — |
case-06 | pass→pass | 11,053 | 8,289 | -25% | 1 | 1 | 0% | 1,857 | 2,679 | +44% | 0 | 0 | — |
case-08 | pass→pass | 16,531 | 11,154 | -33% | 1 | 1 | 0% | 2,526 | 3,028 | +20% | 0 | 0 | — |
case-09 | pass→pass | 9,857 | 7,068 | -28% | 1 | 1 | 0% | 1,628 | 2,313 | +42% | 0 | 0 | — |
case-10 | pass→fail | 22,513 | 12,502 | -44% | 1 | 1 | 0% | 3,377 | 3,527 | +4% | 0 | 0 | — |
case-11 | pass→pass | 4,667 | 4,477 | -4% | 1 | 1 | 0% | 748 | 1,784 | +139% | 0 | 0 | — |
case-12 | pass→pass | 14,546 | 8,233 | -43% | 1 | 1 | 0% | 2,399 | 2,677 | +12% | 0 | 0 | — |
case-13 | pass→pass | 12,627 | 9,922 | -21% | 1 | 1 | 0% | 2,106 | 2,503 | +19% | 0 | 0 | — |
case-14 | pass→pass | 9,367 | 8,625 | -8% | 1 | 1 | 0% | 1,627 | 2,612 | +61% | 0 | 0 | — |
case-15 | pass→pass | 9,191 | 9,312 | +1% | 1 | 1 | 0% | 1,621 | 2,159 | +33% | 0 | 0 | — |
case-16 | pass→pass | 7,480 | 4,837 | -35% | 1 | 1 | 0% | 1,310 | 1,984 | +51% | 0 | 0 | — |
case-17 | fail→pass | 12,099 | 6,329 | -48% | 1 | 1 | 0% | 2,163 | 2,221 | +3% | 0 | 0 | — |
case-18 | fail→pass | 15,402 | 7,965 | -48% | 1 | 1 | 0% | 2,284 | 2,428 | +6% | 0 | 0 | — |
case-19 | pass→pass | 15,524 | 13,601 | -12% | 1 | 1 | 0% | 1,891 | 3,172 | +68% | 0 | 0 | — |
case-20 | pass→pass | 14,509 | 13,503 | -7% | 1 | 1 | 0% | 2,854 | 3,498 | +23% | 0 | 0 | — |
case-21 | pass→pass | 8,464 | 8,172 | -3% | 1 | 1 | 0% | 1,538 | 2,540 | +65% | 0 | 0 | — |
case-22 | pass→pass | 8,987 | 8,231 | -8% | 1 | 1 | 0% | 1,646 | 2,697 | +64% | 0 | 0 | — |
DecimalAI ran this skill against gemini-3.6-flash twice over the same eval suite — once with the skill loaded and once without — and compared the two runs case by case. 22 cases were attempted. The headline lift of +5 percentage points is the difference between those two pass rates over the 22 comparable cases. 1 case got worse with the skill loaded, and it is included in that figure.
Without the skill loaded, the model failed this case. With it loaded, the same prompt on the same model passed. This is one improved case from the latest verified run; every case, including any that regressed, is in the table above.
Other measured skills in the registry, with their headline benchmark lift.