0Pricing
Frontend Academy · 课时

useFetch 与 useAsyncData

使用 useFetch 和 useAsyncData 获取服务器端数据,处理等待和错误状态,并了解 Nuxt 如何对客户端进行水合。

useFetch 与 useAsyncData 是 CoddyKit 上的免费 Frontend Academy 课时。 这是第 2 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 Frontend Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 Frontend Academy 课程共包含 4 节课。

Nuxt 3 中的数据获取

Nuxt 提供两个主要的组合式函数来获取数据:useFetch(基于 URL,在底层调用 fetch)和 useAsyncData(可接受任意异步函数,并使用唯一键进行缓存和去重)。

useFetch——快速方式

传入 URL 后,Nuxt 会在 SSR 期间获取数据,在客户端进行激活,并防止客户端在激活期间重复获取数据。

<script setup>
const { data: posts, pending, error } = await useFetch('/api/posts');
</script>

<template>
  <div v-if="pending">Loading...</div>
  <div v-else-if="error">{{ error.message }}</div>
  <ul v-else>
    <li v-for="p in posts" :key="p.id">{{ p.title }}</li>
  </ul>
</template>

为什么激活时不会重复获取数据

Nuxt 会将获取的数据序列化到 SSR HTML 载荷中。在客户端,useFetch 会从该载荷中激活数据,因此不会发起第二次网络请求。这是 SSR 优化的关键。

useAsyncData——灵活的异步方式

当数据获取并非简单的 URL 请求时使用它,例如数据库查询、自定义逻辑或多步骤请求。

<script setup>
const { data: user } = await useAsyncData('user-profile', async () => {
  const me = await $fetch('/api/me');
  const stats = await $fetch(`/api/users/${me.id}/stats`);
  return { ...me, stats };
});
</script>

缓存键很重要

useAsyncData 的第一个参数是唯一的缓存键。在多个组件之间共享相同的键时,系统会对请求去重并复用结果。不同的键表示独立的获取操作。

// Two components calling useFetch('/api/posts') share one request
// Two components calling useFetch('/api/posts', { key: 'a' }) and { key: 'b' } fetch twice

刷新与延迟加载

两个组合式函数都会返回 refresh() 以重新获取数据,并接受 { lazy: true } 以跳过阻塞 SSR(数据会在页面渲染后加载)。

const { data, refresh } = await useFetch('/api/posts');

async function onSave() {
  await $fetch('/api/posts', { method: 'POST', body: newPost });
  await refresh();
}

// Or lazy mode:
const { data, pending } = useFetch('/api/posts', { lazy: true });

监听与响应式 URL

为 URL 传入一个函数——它具有响应性。当依赖项发生变化时,会重新获取数据。

<script setup>
const page = ref(1);
const { data } = await useFetch(() => `/api/posts?page=${page.value}`);
// Changing page.value re-runs the fetch
</script>

请求选项

useFetch 接受与 fetch 相同的选项——method、body、headers,以及 default 和 transform 等 Nuxt 专用选项。

const { data } = await useFetch('/api/posts', {
  method: 'POST',
  body: { title: 'Hello' },
  headers: { 'X-Custom': '1' },
  transform: (raw) => raw.items.map(transformItem),
  default: () => []
});

$fetch——命令式获取

$fetch 是 Nuxt 的通用获取器(底层使用 ofetch)。它不会自动跟踪激活状态。请在事件处理程序和数据变更中使用它。

async function deletePost(id) {
  await $fetch(`/api/posts/${id}`, { method: 'DELETE' });
  await refresh();
}

错误处理

在获取处理程序中抛出错误即可显示该错误。页面可以使用 ~/error.vue 显示自定义错误页面。

// error.vue at project root
<script setup>
const props = defineProps<{ error: any }>();
</script>

<template>
  <div>
    <h1>{{ error.statusCode }}</h1>
    <p>{{ error.message }}</p>
    <button @click="clearError({ redirect: '/' })">Home</button>
  </div>
</template>

身份验证与 Cookie

useFetch 会在 SSR 期间自动转发 Cookie,因此经过身份验证的请求在服务器和客户端上都能正常工作,无需手动处理 Cookie。

useFetch 与 useAsyncData——何时使用

useFetch:简单的基于 URL 的请求(占 95% 的情况)。useAsyncData:自定义异步逻辑、多步骤组合以及非 URL 数据源(例如通过 server/utils 访问数据库)。

快速检查

为什么 Nuxt 3 中的 useFetch 可以防止页面在客户端激活时发起重复的网络请求?

回顾:useFetch 与 useAsyncData

useFetch:适用于基于 URL 的场景,占 95%。useAsyncData:适用于带有唯一缓存键的自定义异步逻辑。两者都会从 SSR 载荷中进行水合(不会重复请求)。使用 refresh() 重新获取数据,使用 lazy:true 跳过会阻塞 SSR 的请求。响应式 URL 会触发重新获取。使用 $fetch 执行命令式变更。error.vue 负责处理错误。SSR 期间会自动转发 Cookie。

常见问题解答

「useFetch 与 useAsyncData」课时是免费的吗?

是的 — 「useFetch 与 useAsyncData」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 Frontend Academy 课程的其余内容,请升级到 CoddyKit PRO。 Frontend Academy 课程共包含 4 节课。

「useFetch 与 useAsyncData」这节课中我会学到什么?

使用 useFetch 和 useAsyncData 获取服务器端数据,处理等待和错误状态,并了解 Nuxt 如何对客户端进行水合。 你通过在浏览器中直接运行的动手代码来练习 Frontend Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。

学习 Frontend Academy 需要有经验吗?

无需任何先前经验。CoddyKit 上的 Frontend Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 2 节课,共 4 节。

「useFetch 与 useAsyncData」课时需要多长时间?

大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。

我能在这节 Frontend Academy 课中编写并运行代码吗?

能。每节 Frontend Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。

此课程中的所有课时

  1. 基于文件的路由与自动导入
  2. useFetch 与 useAsyncData
  3. Nuxt 模块:图像、身份验证与国际化
  4. 部署:静态模式与 SSR
← 返回 Frontend Academy