# [Nuxt] Nuxt 3 - Data fetching
###### tags: `Nuxt`
## $fetch
:::info
* [官方文件 - Data fetching](https://nuxt.com/docs/getting-started/data-fetching#fetch "Data fetching · Get Started with Nuxt")
* [官方文件 - $fetch Utils](https://nuxt.com/docs/api/utils/dollarfetch "\$fetch · Nuxt Utils")
:::
以前會需要自己引入第三方套件去處理非同步請求,現在 Nuxt 3 整合 [ofetch](https://github.com/unjs/ofetch "GitHub - unjs/ofetch"),提供一個叫做 $fetch 方法,讓開發人員可以在 server 端與 client 端處理非同步
## useAsyncData
:::info
[官方文件]()
* [官方文件 - Data fetching](https://nuxt.com/docs/getting-started/data-fetching#useasyncdata "Data fetching · Get Started with Nuxt")
* [官方文件 - useAsyncData composable](https://nuxt.com/docs/api/composables/use-async-data "useAsyncData · Nuxt Composables")
:::
* 會等呼叫的 API 回傳後才開始渲染頁面
* 需要 key 或複雜的需求時使用
* 寫法:`useAsyncData(key, handler, options?)` 或 `useAsyncData(handler, options?)`
### 參數
* key: 唯一值,避免在 server 端和 client 端重複獲取資料,若沒寫會自動產生。可在其他組件調用。
* handler: 返回非同步 function 的值
* options
* lazy: 是否於載入路由後才開始執行非同步 function
* 預設 `false`,會阻止路由載入
* default: 在非同步 function 返回值前設定資料預設值。在 `lazy: true` 時特別有用。
* server: 是否在 server 端獲取資料
* 預設 `true`
* transform: 修改 handler 回傳的值
* pick: 從 handler 回傳的結果選擇指定的 key,有助於[最小化 payload size](https://nuxt.com/docs/getting-started/data-fetching#minimize-payload-size "Minimize payload size · Data fetching · Get Started with Nuxt"),若要處理多個 object,使用 `transform`
* type: `string[]`
* watch: 監聽 ref / reactive 資料,有變化時 auto-refresh。適用於資料分頁、篩選結果、搜尋等。
* immediate: 是否立即觸發請求
* 預設 `true`
### Return Values
* data: 非同步 function 回傳的值
* pending: Boolean。非同步請求是否完成
* refresh/execute: 重新執行 handler function
* error: 獲取資料失敗的資訊
* status: request 狀態
* 值有 `idle`、`pending`、`success`、`error`
## useFetch
:::info
* [官方文件 - Data fetching](https://nuxt.com/docs/getting-started/data-fetching#usefetch "Data fetching · Get Started with Nuxt")
* [官方文件 - useFetch composable](https://nuxt.com/docs/api/composables/use-fetch "useFetch · Nuxt Composables")
:::
* 封裝 `useAsyncData()` 和 `$fetch()`
* 單純 Get 資料渲染至網頁時使用
* 寫法:`useFetch(url, options?)`
### 參數
* url: URL
* options
* key
* lazy
* default
* server
* transform
* pick
* watch
* immediate
* method: 請求的方法
* query/params: 查詢參數
* body: Request body
* headers: Request headers
* baseURL: Base URL for the request
### Return Values
和 [`useAsyncData`](#Return-Values) 相同
## useLazyAsyncData
等同 `useAsyncData(key, handler, { lazy: true })`,需要使用 `pending` 自行處理 loading 狀態
## useLazyFetch
等同 `useFetch(url, { lazy: true })`,需要使用 `pending` 自行處理 loading 狀態
## 範例
```javascript
<script setup>
// 下面寫法會一個一個執行,造成阻塞,建議換成 Promise.all
// const { data: fetchData } = await useFetch('https://xxx.xxx');
// const { data: asyncData, refresh } = await useAsyncData(
// 'key',
// () => $fetch('https://xxx.xxx')
// );
// 會在 Promise.all 一起執行, 等資料都跑完再一起回傳
const [{ data: fetchData }, { data: asyncData, refresh }] = await Promise.all([
useFetch('https://xxx.xxx'),
useAsyncData(
'key',
() => $fetch('https://xxx.xxx'),
),
]);
async function submit() {
try {
const response = await $fetch(
'https://xxx.xxx',
{
method: 'POST',
body: {
key: 'value',
},
},
)
console.log('response: ', response);
} catch (error) {
console.log('error: ', error)
}
}
</script>
<template>
<button @click="submit">Submit</button>
</template>
```
## 重新取得資料
:::info
* [官方文件 - Data fetching](https://nuxt.com/docs/getting-started/data-fetching#refresh-and-execute "Data fetching · Get Started with Nuxt")
* [官方文件 - refreshNuxtData Utils](https://nuxt.com/docs/api/utils/refresh-nuxt-data "refreshNuxtData · Nuxt Utils")
* [官方文件 - clearNuxtData Utils](https://nuxt.com/docs/api/utils/clear-nuxt-data "clearNuxtData · Nuxt Utils")
:::
* 使用 `useAsyncData()` 或 `useFetch()` Return Values 的 `refresh`
* 使用 `refreshNuxtData(key)`:只會重新取得指定 key 的資料
* 使用 `refreshNuxtData()`:所有 `useAsyncData` 和 `useFetch` 都會重新取得資料
### 刪除緩存資料
`clearNuxtData(keys?: string | string[] | ((key: string) => boolean))`:刪除指定 key 的緩存資料,若未指定,則刪除所有緩存資料
## 搭配 axios
```javascript
<script setup>
// 只能 return response 的 data,若 return 整個 response 會壞掉
import axios from "axios";
const { data: axiosData } = await useAsyncData(
'key',
async () => {
const resp = await axios.get('https://xxx.xxx');
return resp.data;
},
);
</script>
```
## 傳遞 Headers 和 cookies
:::info
[官方文件](https://nuxt.com/docs/getting-started/data-fetching#passing-headers-and-cookies "Data fetching · Get Started with Nuxt")
:::
---
:::info
建立日期:2023-08-13
更新日期:2023-09-05
:::