Nuxt.js 中的 useFetch
和 useAsyncData
是专为服务端渲染(SSR)和客户端渲染优化的数据获取工具,其行为会根据 Nuxt 的渲染模式(SSR、静态生成、客户端渲染)和环境(服务端/客户端)自动适配。以下是它们的运行机制和原理:
一、基本行为
-
服务端运行阶段(SSR/预渲染):
- 在首次页面请求时(服务端渲染或静态生成阶段),
useFetch
和useAsyncData
一定会运行一次,用于获取初始数据并直接嵌入到 HTML 中。 - 数据会被序列化到
window.__NUXT__
对象中,供客户端复用。
- 在首次页面请求时(服务端渲染或静态生成阶段),
-
客户端运行阶段:
- 当页面在客户端加载时(如通过
<NuxtLink>
导航或浏览器直接访问),Nuxt 默认会复用服务端获取的数据,不会重复执行请求。 - 如果通过客户端路由跳转到新页面(非首次加载),
useFetch
和useAsyncData
会在客户端再次运行,发起新的网络请求。
- 当页面在客户端加载时(如通过
二、核心原理
-
自动去重:
- 通过唯一的
key
标识请求,避免重复获取相同数据。 - 服务端数据会通过
window.__NUXT__
注入客户端,客户端优先使用预加载数据。
- 通过唯一的
-
环境感知:
- 在服务端运行时,直接执行数据获取逻辑。
- 在客户端运行时,根据
server
选项决定是否发起请求:// 默认行为:服务端运行一次,客户端不重复运行 useFetch('/api/data'); // 强制仅在客户端运行 useFetch('/api/data', { server: false });
-
Hydration 协调:
- 客户端会对比服务端预取的数据,确保 Vue 组件能正确“激活”(hydration),避免界面闪烁。
三、关键配置选项
-
server
(默认true
):true
: 服务端运行,客户端复用数据。false
: 仅在客户端运行。
-
lazy
(默认false
):true
: 允许组件渲染后再异步获取数据(需手动处理加载状态)。
-
immediate
(默认true
):false
: 不自动执行,需手动调用refresh()
。
四、示例场景
场景 1:静态生成页面(SSG)
// pages/index.vue
const { data } = await useFetch('/api/data');
- 构建时:服务端运行一次,数据嵌入 HTML。
- 客户端访问:直接使用预加载数据,不发起请求。
场景 2:客户端动态数据
// 仅在客户端获取数据
const { data } = await useFetch('/api/data', { server: false });
- 服务端:不执行。
- 客户端:每次加载页面时发起请求。
场景 3:SPA 应用内导航
// 通过 <NuxtLink> 跳转到页面
const { data, refresh } = await useFetch('/api/data');
- 首次加载:服务端运行。
- 客户端导航:再次发起请求,更新数据。
五、总结
- 默认行为:服务端运行一次,客户端复用数据,避免重复请求。
- 客户端触发条件:路由跳转、手动调用
refresh()
、配置server: false
。 - 优化点:通过合理配置
server
和lazy
,可灵活控制数据加载策略。
理解这些机制后,可以更好地设计高性能的 Nuxt 应用,平衡服务端预渲染和客户端动态更新的需求。