# [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 :::