Skip to content
On this page

Nuxt请求数据的方式

为什么需要$fetch?

  • 首屏渲染,请求调用发生在服务端;
  • 客户端激活之后,调用发生在客户端。 这导致我们首先需要判断代码执行环境,其次发送请求的 API 可能不同,另外如果在客户端发送请求到其他接口服务器还会存在跨域问题,需要给项目配代理,这就是 Nuxt3 为什么替我们封装了 $fetch ,它全局可用,可以智能处理调用时机,还能统一 API,避免配置代理。

$fetch

js
const { data } = await $fetch('/api/hello', { query: { name: 'tom' } })
const { result } = await $fetch('/api/post', { method: 'post', body: newPost })

通过$fetch这种方式,如果要加上一些loading,error效果,通常需要自己封装进行实现,比较麻烦。

useFetch

useFetch方法签名

js
function useFetch(
  url: string | Request | Ref<string | Request> | () => string | Request,
  options?: UseFetchOptions<DataT>
): Promise<AsyncData<DataT>>

type AsyncData<DataT> = {
  data: Ref<DataT> // 返回数据
  pending: Ref<boolean> // 加载状态
  refresh: (opts?: { dedupe?: boolean }) => Promise<void> // 刷新数据
  execute: () => Promise<void> // 同 refresh,没有去重选项
  error: Ref<Error | boolean> // 错误信息
}

useFetch的基本使用

js
const { data: posts, pending, error } = await useFetch('/api/posts')

可以看到,会自动把请求状态,错误状态暴露出来,我们只需要根据这些状态决定我们的页面状态即可。

useLazyFetch

该方法等效于useFetch设置了lazy选项为 true,不同之处在于它不会阻塞路由导航,这意味着我们需要处理 data 为 null 的情况(或者通过 default 选项给 data 设置一个默认值)。

前面的例子,将 useFetch 替换为 useLazyFetch 同样可行:

js
const { data: posts, pending, error } = await useLazyFetch('/api/posts')

useAsyncData

该方法和 useFetch 相比功能上是相同的, 但是更底层。我们需要提供一个用于缓存去重的 key 和数据请求的处理函数。也就是说,useFetch 相当于:useAsyncData(key, () => $fetch(url))useAsyncData签名如下,因此 useAsyncData 有两种用法:一种传 key,一种不传 key,但是即使你不传,Nuxt 也会帮你生成一个

js
function useAsyncData(
  handler: (nuxtApp?: NuxtApp) => Promise<DataT>,
  options?: AsyncDataOptions<DataT>
): AsyncData<DataT>
function useAsyncData(
  key: string,
  handler: (nuxtApp?: NuxtApp) => Promise<DataT>,
  options?: AsyncDataOptions<DataT>
): Promise<AsyncData<DataT>>

useAysncData基本使用

js
const router = useRoute();
const fetchPost = () => $fetch(`/api/detail/${router.params.id}`);
const { data, pending } = await useAsyncData(fetchPost);

useLazyAsyncData

该方法等效于useAsyncData,仅仅设置了lazy选项为true,也就是它不会阻塞路由导航,这意味着我们需要处理 data 为 null 的情况,或者通过 default 选项给 data 设置一个默认值。

刷新数据

有时候页面数据是需要刷新的,比如:翻页、条件过滤、搜索等。

我们可以使用useFetch()等 API 返回的refresh()刷新数据。需要注意,如果请求的 key 参数没有发生变化,我们实际上拿到的还是之前缓存的结果。例如下面代码执行 refresh() 并不会得到最新数据:

js
const { data, refresh } = useFetch('/api/somedata')
// 数据并没有刷新!
refresh()

而想要获取最新数据,就要在 url 中添加一个参数,并作为函数返回值传给useFetch

js
// url需要改为由函数返回 必须
const { data, refresh } = useFetch(() => `/api/somedata?page=${page}`)
// 数据刷新!
page++
refresh()

Released under the MIT License.