因为Nuxt3
是SSR
的方案,所以你可能不仅仅只是想要在浏览器端发送请求获取数据,还想在服务器端就获取到数据并渲染组件。
Nuxt3
提供了 4 种方式使得你可以在服务器端异步获取数据
注意:他们只能在**
setup
**或者是生命周期钩子
中使用
项目中可以在pages
目录、components
目录和plugins
目录下使用 useAsyncData 异步获取数据
//用法
const {
data: Ref,// 返回的数据结果
pending: Ref,// 是否在请求状态中
refresh: (force?: boolean) => Promise,// 强制刷新数据
error?: any // 请求失败返回的错误信息
} = useAsyncData(
key: string, // 唯一键,确保相同的请求数据的获取和去重
fn: () => Object,// 一个返回数值的异步函数
options?: { lazy: boolean, server: boolean }
// options.lazy,是否在加载路由后才请求该异步方法,默认为false
// options.server,是否在服务端请求数据,默认为true
// options.default,异步请求前设置数据data默认值的工厂函数(对lazy:true选项特别有用)
// options.transform,更改fn返回结果的函数
// options.pick,只从数组中指定的key进行缓存
)
可以考虑设置 lazy:true 配合 loading 状态加载器的方式,能够带来更好的用户体验。
// server/api/count.ts-例子
let counter = 0
export default () => {
counter++
return JSON.stringify(counter)
}
// app.vue-例子
Page visits: {{ data }}
这个封装方法等同于是,使用useAsyncData
方法默认配置了lazy:true
,执行异步函数时不会阻塞路由的执行。也意味着你必须处理数据为null
的情况(比如说,在default
返回的工厂函数中设置一个默认值)。
在pages
目录、components
目录和plugins
目录下使用useFetch
也同样可以获取到任意的 URL 资源。该方法实际上是对 useAsyncData 和$fetch 的封装,提供了一个更便捷的封装方法。(它会根据 URL 和 fetch 参数自动生成一个 key,同时推断出 API 的响应类型)
//useFetch用法
const {
data: Ref,
pending: Ref,
refresh: (force?: boolean) => Promise,
error?: any
} = useFetch(url: string, options?)
//可以看到useFetch和useAsyncData的返回对象是一样的,useFetch传参更便捷,不需要在fn中手动使用$fetch
useAsyncData(key: string,fn: () => Object,options?: { lazy: boolean, server: boolean })
//例子
Page visits: {{ data.count }}
这个封装方法等同于是,使用useFetch
方法默认配置了lazy:true
,执行异步函数时不会阻塞路由的执行。也意味着你必须处理数据为null
的情况(比如说,在default
返回的工厂函数中设置一个默认值)。
通过异步请求回来的数据都会存储在页面 payload 中。意味着,可能会存在没有用在你的组件的数据也加载到了 payload 中。我们强烈推荐你只选取必须使用在组件上的数据
// /api/mountains/everest
{
"title": "Mount Everest",
"description": "Mount Everest is Earth's highest mountain above sea level, located in the Mahalangur Himal sub-range of the Himalayas. The China–Nepal border runs across its summit point",
"height": "8,848 m",
"countries": [
"China",
"Nepal"
],
"continent": "Asia",
"image": "https://upload.wikimedia.org/wikipedia/commons/thumb/f/f6/Everest_kalapatthar.jpg/600px-Everest_kalapatthar.jpg"
}
// 组件中只使用到了title和description,useFetch使用option的pick参数来指定key
{{ mountain.title }}
{{ mountain.description }}
受 Vue3 的影响,如果你使用了async setup()
的形式,当前组件的实例会在第一个异步操作之后丢失。如果你想要使用多个异步操作,比如执行多个 useFetch,你需要使用或者将多个请求封装在一起请求(使用 Promise.all 将多个请求装在一起)。 我们强烈建议使用
形式,它解决了采用顶层 await的限制
{{ organization.login }}
{{ organization.description }}