nuxt请求机制
useFetch
useFetch是Nuxt 3中最常用的数据获取方法之一。它是useAsyncData和$fetch的组合。
特点:
- 默认根据url请求进行缓存
- 自动处理加载状态、错误状态和数据缓存
- 支持服务器端渲染(SSR)
- 可以在组件或页面中使用
- 返回响应数据、加载状态和错误信息
场景:
- 避免重复请求,如使用了useFetch,首先在ssr请求一次,在客户端渲染的时候,就可以复用缓存的数据,避免重复请求
- 保证数据一致:确保在服务端和客户端的数据请求一致
如同调试请求
- useFetch 默认在服务端渲染期间完成请求,处理数据, 然后再把请求结果给到客户端处理
- 因此在浏览器客户端network是看不到请求的,因为已经在服务端node中完成了请求
通常我们习惯在浏览器network查看网络请求,但是由于是服务端渲染,和传统的单页面应用是有区别的
- 可以服务端日志中,查看请求日志
- Nuxt 服务端控制台:在服务端环境里打印
useFetch请求的参数
| 方法 | 能抓取 SSR 请求吗 | 说明 |
|---|---|---|
| 浏览器 network | ❌ | SSR 请求在 Node 发出,浏览器看不到 |
| Node 配置代理(Charles/Fiddler/mitmproxy) | ✅ | Node 请求走代理就能抓到 |
| SSR 日志打印 | ✅ | 控制台直接打印请求/响应,调试最方便 |
| 后端 API 日志 | ✅ | 最直接,看到所有请求和返回 |
| CSR 再发一次请求 | ✅ | 可以在浏览器 network 中看到,但会多一次请求 |
useFech执行流程
- 1、检查缓存
- 2、状态初始化
- 3、响应式数据创建
- 4、ssr渲染 =>客户端执行
- 5、请求发送
- 6、数据处理
- 7、状态更新
- 8、缓存更新
- 9、返回响应式对象
$fetch
$fetch是一个全局可用的函数,用于发起HTTP请求。
特点:
- 基于Fetch API,但提供了更好的类型支持
- 可以在客户端和服务器端使用
- 不会自动处理SSR或数据缓存
$fetch执行流程
- 1、$fetch调用
- 2、请求发送
- 3、数据返回
useAsyncData
useAsyncData是一个更通用的异步数据处理工具。
useAsyncData 的优势在于 SSR渲染期间获取数据,客户端进行复用,避免在客户端期间重复请求数据
特点:
- 支持服务端渲染和客户端渲染
- 可以处理任何异步操作,不仅限于HTTP请求
- 可以在组件或页面中使用
- 提供更多的控制选项
示例
<script setup>
const { data: user, pending, error } = await useAsyncData('user', () => $fetch('/api/user'))
</script>
<template>
<div v-if="pending">加载中...</div>
<div v-else-if="error">请求失败:{{ error.message }}</div>
<div v-else>用户名:{{ user.name }}</div>
</template>
- 服务端 SSR 阶段拉取
/api/user - 客户端执行阶段复用
user数据 - 如果
user数据在客户端已经存在,则不会再重复发送请求
useFetch和$fetch
| 特性 | $fetch | useFetch |
|---|---|---|
| 是否缓存 | ❌ 默认不缓存 | ✅ 默认缓存(用于 SSR/客户端间复用) |
| 是否自动追踪响应状态 | ❌ 否 | ✅ 是(有 pending, error, statusCode 等) |
| 是否支持懒加载、只客户端执行等 | ❌ 否 | ✅ 是 |
| 适合使用场景 | 直接发请求(如点击按钮后) | 页面加载时自动拉取数据 |
| 是否可服务端使用 | ✅ | ✅ |
useFetch和$fetch使用场景
使用useFetch场景
- 1、首次页面加载/页面刷新 (需要ssr,当客户端渲染复用数据,避免重复请求)
- 注意的是,当发现数据没更新,使用了上一次的数据,需要检查缓存问题
- 如果请求的url相同会返回相同的数据,有一些情况即使url相同,但是请求头不同,比如在请求头加了语言标识,这时候如果使用缓存数据,就会有问题
- 检查请求头是否不一致
- 设置key来避免url相同导致缓存
- 如key => url (请求url) + method (请求方法) + header.lang (请求头语言表示)
- 注意的是,当发现数据没更新,使用了上一次的数据,需要检查缓存问题
- 2、需要缓存机制
- 3、需要响应式数据
使用$fetch场景
- 1、客户端路由导航
- 因为首次加载或者页面刷新,需要ssr,需要通过useFetch来避免重复渲染,后续的路由跳转导航都是客户端渲染,不涉及ssr,因此可通过$fetch
- 2、一次性数据获取
- 3、不涉及数据缓存
- 4、对比useFetch性能更好
- 速度更快、无缓存机制干扰