Nuxt 数据获取
本文将介绍 Nuxt 中的 3 个数据获取 API,分析其设计缘由和各自的优势。
一、数据获取的问题及其解决方案
在 Nuxt 中,由于其特殊性,存在着若干个与数据获取相关的问题,如下:
1. 接口调用方式问题
在 Nuxt 中,由于同时存在多种渲染模式,代码有可能运行于服务端和客户端,因此不得不考虑接口的调用时机。
在渲染模式为 SSR2.0 时:
- 服务端进行首屏渲染时,渲染者与接口处理者为同一个程序,只需要进行本地方法调用即可
- 在后续以浏览器为主导的 SPA 模式中,接口调用发生在浏览器,需要发送 HTTP 请求至服务端处理
2. 接口重复调用问题
若渲染方式为 SSR2.0,则有可能发生 “接口重复调用问题”。具体来说,针对首屏:
- 在服务端中,为了构建页面,首先进行了第一次接口调用
- 浏览器渲染首屏页面后,进一步进行 SPA 化,在此过程中,由于 Vue 实例的状态并不会从服务器传输到浏览器,因此,浏览器必须要再次调用接口以获取数据
使用 Nuxt 提供的 useFetch
和 useAsyncData
,可以借助 Nuxt 的 payload 传递数据,并在需要时优先从中提取,从而避免 “接口重复调用问题”。
3. 异步组件加载问题
若组件为异步组件(即组件存在异步依赖),则组件存在加载状态、最终状态等不同的状态。这就要求开发者不仅要编写最终状态下的界面,还需要额外编写等待异步依赖时的加载界面。为了简化这一过程,Vue3 引入了 Suspense
组件。它允许组件 “等待” 某些异步操作完成,并在此期间显示一个备用内容(如加载指示器),直到异步操作完成,主内容才被渲染。
在路由跳转时,Nuxt 会利用 Suspense
组件,在下一页面的组件加载完成之前,延缓页面的跳转,从而避免 “异步组件加载问题”。
为了达到这一目的,要求开发者使用 async setup
,并确保通过 await
关键字等待每一个网络请求的完成。Nuxt 提供的数据获取 API 能够很好地实现这一点。
4. 解决方案
为了解决这些问题,Nuxt 提供了 useFetch
、useAsyncData
、$fetch
等 API。
二、useFetch
useFetch
是 Nuxt 最推荐的数据获取方式,它是 useAsyncData
和 $fetch
的结合。
useFetch(url)
等效于 useAsyncData(() => $fetch(url))
。
useFetch
的返回值格式如下:
1 |
|
useFetch
存在一个可选参数,该参数为对象,可以用于控制请求,包括缓存与否、调用时机等。
三、useAsyncData
useAsyncData
负责处理异步数据,它将提供缓存功能,以避免异步数据的重复获取。
useAsyncData
接收两个参数,
- key:
- 唯一标识,用于缓存 fun 的结果
- 可以不传递,将自动生成一个值
- fun:
- 查询函数,应该返回一个包含了异步数据的 Promise
useAsyncData
的返回值格式与 useFetch
相同。
useAsyncData
也存在一个与 useFetch
相同的可选参数。
四、$fetch
$fetch
解决了 “接口调用方式问题”,可以配合 Nuxt 解决 “异步组件加载问题”,并没有解决 “接口重复调用问题”。
因此,建议在以下两种前提下使用 $fetch
:
只能由用户交互触发
例如,请求需要用户手动点击按钮后才会发送,因此,”接口重复调用问题” 自然得到解决
与
useAsyncData
配合使用