标准答案
- useAsyncData 接收 key 和异步函数,适合读取内容、调用 service、组合多个请求或处理非 HTTP 的异步数据。
- useFetch 更偏 HTTP 请求封装,可以直接传 URL、query、method、body,并和 Nuxt 的 $fetch、SSR 数据注入配合。
- 两者都能在服务端预取数据,并把结果序列化到客户端,减少 hydration 后重复请求。
- key 要稳定且能表达数据身份,否则可能缓存错用、重复请求或不同页面数据互相污染。
- 需要依赖路由参数、筛选条件或用户态时,要明确 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 和空态,页面只在成功路径上可用。