标准答案

  1. useAsyncData 接收 key 和异步函数,适合读取内容、调用 service、组合多个请求或处理非 HTTP 的异步数据。
  2. useFetch 更偏 HTTP 请求封装,可以直接传 URL、query、method、body,并和 Nuxt 的 $fetch、SSR 数据注入配合。
  3. 两者都能在服务端预取数据,并把结果序列化到客户端,减少 hydration 后重复请求。
  4. key 要稳定且能表达数据身份,否则可能缓存错用、重复请求或不同页面数据互相污染。
  5. 需要依赖路由参数、筛选条件或用户态时,要明确 watch、lazy、server、default、transform 等选项对请求时机的影响。

题目解析

简单 HTTP 请求优先 useFetch,复杂数据编排或非 HTTP 来源可以用 useAsyncData。

Nuxt 数据获取题要讲清楚服务端和客户端复用。很多重复请求、闪烁和 hydration 问题都来自 key 或请求时机不稳定。

业务页面里还要考虑错误态、pending 态、空态和刷新动作,不能只写 await useFetch 就结束。

代码示例

下面展示了 useFetch 用于普通接口,useAsyncData 用于组合服务。

Vue
<script setup lang="ts">
const route = useRoute()

const { data, pending, error, refresh } = await useFetch('/api/articles', {
  query: {
    page: route.query.page || 1
  }
})
</script>
TypeScript
const { data: detail } = await useAsyncData(
  () => `article-${route.params.slug}`,
  async () => {
    const article = await articleService.find(route.params.slug as string)
    const related = await articleService.related(article.cluster)
    return { article, related }
  }
)

常见误区

  • 所有异步数据都用 useFetch,导致非 HTTP 数据编排变得别扭。
  • 不给稳定 key,或者 key 没有包含路由参数和筛选条件。
  • 忽略 pending、error、refresh 和空态,页面只在成功路径上可用。

作者信息