nuxt 为我们提供了 useFetch 和 useAsyncData 我们应该用哪个呢?
如何在数据变化后自动重新加载数据?
在使用 useFetch 时,需要在数据变化后自动请求数据的时候,我们不应该在参数中进行解包
1 2 3 4 5 6 7 8 9 10 11 12 13
| <script lang="ts" setup> const page = ref(1) const { data } = await useFetch("/api/result", { query: { page: page.value, }, method: "POST", }) </script>
<template> <button @click="page++">更改分页</button> </template>
|
上面这段代码相当于下面这段代码,在 page 变化时不会自动进行数据的重新加载。
1 2 3 4 5 6 7 8 9 10 11 12 13
| <script lang="ts" setup> const page = ref(1) const { data } = await useFetch("/api/result", { query: { page: 1, }, method: "POST", }) </script>
<template> <button @click="page++">更改分页</button> </template>
|
我们我们如果需要在 page 变化时重新调用接口,我们不需要对 page 进行解包
1 2 3 4 5 6 7 8 9 10 11 12 13
| <script lang="ts" setup> const page = ref(1) const { data } = await useFetch("/api/result", { query: { page: page, }, method: "POST", }) </script>
<template> <button @click="page++">更改分页</button> </template>
|
下面两段代码实现的效果是一致的,会在在 page 变化时重新请求数据
1 2 3 4 5 6 7
| const page = ref(1) const { data } = await useFetch("/api/result", { query: { page: page, }, method: "POST", })
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| const page = ref(1) const { data } = await useAsyncData("result", async () => $fetch( "/api/result", { query: { page: page.value, }, method: "POST", }, { watch: [page], } ) )
|
useFetch
近似等同于 useAsyncData
+ `$fetch
什么时候会用到 useAsyncData?
我们需要一次请求多个数据,比如我们需要请求用户信息和文章列表,我们可以使用 useAsyncData 来实现
1 2 3 4 5 6 7 8
| const { userInfo } = await useAsyncData("userInfo", async () => { const [user, articles] = await Promise.all([$fetch("/api/user"), $fetch("/api/articles")])
return { user, articles, } })
|
或者我们会有一些其他的第三方提供好的接口和方法,我们也可以使用 useAsyncData 来实现
1 2 3 4 5 6 7
| import { fetchData } from "other-api"
const { data } = await useAsyncData("otherData", async () => { const result = await fetchData() return result })
|
useAsyncData 和 useFetch 对返回值的处理
有时我们需要的数据只是接口返回值的一部分,那么我们可以使用 transform 属性来处理返回值
1 2 3 4 5 6 7 8 9
| const { data } = await useAsyncData("result", () => $fetch("/api/result"), { transform: (data) => { return { id: data.id, name: data.name, } }, })
|
如果返回值是多个数据,也可以使用 transform 函数来处理
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| const { userInfo } = await useAsyncData( "userInfo", async () => { const [user, articles] = await Promise.all([$fetch("/api/user"), $fetch("/api/articles")])
return { user, articles, } }, { transform: (data) => { return { user: { username: data.user.username, email: data.user.email, }, articles: data.articles.map((article) => ({ title: article.title, content: article.content, })), } }, } )
|
结论
- $fetch 没有响应性
- useAsyncData 可以配置 watch 属性在某些字段变更时具备响应性
- useFetch 可以自动扫描方法内的响应式数据,并在数据变更时重新加载数据
我们一般情况下使用 useFetch,useFetch 为我们提供的自动重新加载数据会有更好的 DX,我们不在需要手动处理什么时候重新加载数据,只要保证参数中的数据是响应式的即可;如果你有特殊的情况,可以使用 useAsyncData 自己处理一些数据,而且结合 useAsyncData 提供的一些属性比如 watch 也可以尽可能的更加友好的处理一些数据的自动重新加载;$fetch 来自于 ofetch 它更像是 axios 之类 HTTP 请求库,需要手动对每次请求做出判断。
如果实在服务端使用,那么就只能使用 $fetch