useAsyncData
useAsyncData 提供對非同步解析資料的訪問,它是一個對 SSR 友好的可組合函式。
在您的頁面、元件和外掛中,您可以使用 useAsyncData 訪問非同步解析的資料。
useAsyncData
是一個可組合函式,旨在直接在 Nuxt 上下文中呼叫。它返回響應式可組合函式,並處理將響應新增到 Nuxt 有效負載中,以便它們可以從伺服器傳遞到客戶端,**而無需在頁面水合時在客戶端重新獲取資料**。使用
app/pages/index.vue
<script setup lang="ts">
const { data, status, error, refresh, clear } = await useAsyncData(
'mountains',
() => $fetch('https://api.nuxtjs.dev/mountains'),
)
</script>
如果您使用的是自定義的 useAsyncData 包裝器,請不要在可組合函式中對其進行 await 操作,因為這可能會導致意外行為。請遵循此指南以獲取有關如何建立自定義非同步資料獲取器的更多資訊。
data
、status
和 error
都是 Vue ref,在 <script setup>
中使用時應透過 .value
訪問,而 refresh
/execute
和 clear
則是普通函式。監聽引數
內建的 watch
選項允許在檢測到任何更改時自動重新執行 fetcher 函式。
app/pages/index.vue
<script setup lang="ts">
const page = ref(1)
const { data: posts } = await useAsyncData(
'posts',
() => $fetch('https://fakeApi.com/posts', {
params: {
page: page.value,
},
}), {
watch: [page],
},
)
</script>
響應式鍵
您可以將計算屬性 ref、普通 ref 或 getter 函式用作 key,從而實現動態資料獲取,並在 key 更改時自動更新。
app/pages/[id].vue
<script setup lang="ts">
const route = useRoute()
const userId = computed(() => `user-${route.params.id}`)
// When the route changes and userId updates, the data will be automatically refetched
const { data: user } = useAsyncData(
userId,
() => fetchUserById(route.params.id),
)
</script>
useAsyncData
是一個由編譯器轉換的保留函式名,因此您不應將自己的函式命名為 useAsyncData
。引數
key
:一個唯一的鍵,用於確保資料獲取可以跨請求正確地去重。如果您不提供鍵,Nuxt 將為useAsyncData
例項生成一個基於檔名和行號的唯一鍵。handler
:一個非同步函式,必須返回一個真值(例如,它不應該是undefined
或null
),否則請求可能會在客戶端重複。handler
函式應**無副作用**,以確保 SSR 和 CSR 水合期間的可預測行為。如果您需要觸發副作用,請使用callOnce
工具來實現。options
:server
:是否在伺服器上獲取資料(預設為true
)lazy
:是否在載入路由後解析非同步函式,而不是阻塞客戶端導航(預設為false
)immediate
:設定為false
時,將阻止請求立即觸發。(預設為true
)default
:一個工廠函式,用於在非同步函式解析之前設定data
的預設值 - 與lazy: true
或immediate: false
選項結合使用時很有用transform
:一個函式,可用於在解析後修改handler
函式的結果getCachedData
:提供一個返回快取資料的函式。返回null
或undefined
將觸發一次獲取。預設情況下,這是僅當const getDefaultCachedData = (key, nuxtApp, ctx) => nuxtApp.isHydrating ? nuxtApp.payload.data[key] : nuxtApp.static.data[key]
nuxt.config
中的experimental.payloadExtraction
啟用時才快取資料。pick
:只從handler
函式結果中挑選此陣列中指定的鍵watch
:監聽響應式源以自動重新整理deep
:以深層 ref 物件返回資料。預設情況下為false
,以淺層 ref 物件返回資料,如果您的資料不需要深度響應式,這可以提高效能。dedupe
:避免同時多次獲取相同的鍵(預設為cancel
)。可能的選項cancel
- 當發出新請求時取消現有請求defer
- 如果存在待處理的請求,則根本不發出新請求
timeout
- 一個以毫秒為單位的數字,表示在請求超時前等待的時間(預設為undefined
,表示沒有超時)
在底層,
lazy: false
使用 <Suspense>
在資料獲取完成之前阻塞路由載入。考慮使用 lazy: true
並實現載入狀態,以獲得更流暢的使用者體驗。共享狀態和選項一致性
當多個 useAsyncData
呼叫使用相同的鍵時,它們將共享相同的 data
、error
和 status
ref。這確保了元件之間的一致性,但要求選項保持一致。
以下選項在所有使用相同鍵的呼叫中**必須保持一致**
handler
函式deep
選項transform
函式pick
陣列getCachedData
函式default
值
以下選項**可以不同**,而不會觸發警告
伺服器
lazy
immediate
dedupe
watch
// ❌ This will trigger a development warning
const { data: users1 } = useAsyncData('users', () => $fetch('/api/users'), { deep: false })
const { data: users2 } = useAsyncData('users', () => $fetch('/api/users'), { deep: true })
// ✅ This is allowed
const { data: users1 } = useAsyncData('users', () => $fetch('/api/users'), { immediate: true })
const { data: users2 } = useAsyncData('users', () => $fetch('/api/users'), { immediate: false })
使用
useAsyncData
建立的帶鍵狀態可以在整個 Nuxt 應用程式中使用 useNuxtData
檢索。返回值
data
:傳入的非同步函式的結果。refresh
/execute
:一個函式,可用於重新整理handler
函式返回的資料。error
:如果資料獲取失敗,則為錯誤物件。status
:一個字串,指示資料請求的狀態idle
:當請求尚未開始時,例如- 當
execute
尚未被呼叫且設定了{ immediate: false }
- 當在伺服器上渲染 HTML 並且設定了
{ server: false }
- 當
pending
:請求正在進行中success
:請求已成功完成error
:請求失敗
clear
:一個函式,可用於將data
設定為undefined
(或options.default()
提供的值,如果提供的話),將error
設定為undefined
,將status
設定為idle
,並標記任何當前待處理的請求為已取消。
預設情況下,Nuxt 會等待 refresh
完成才能再次執行。
如果您尚未在伺服器上獲取資料(例如,使用
server: false
),那麼資料**將不會**在水合完成之前獲取。這意味著即使您在客戶端 await useAsyncData
,data
在 <script setup>
內仍將保持 undefined
。型別
簽名
export function useAsyncData<DataT, DataE> (
handler: (nuxtApp: NuxtApp, options: { signal: AbortSignal }) => Promise<DataT>,
options?: AsyncDataOptions<DataT>
): AsyncData<DataT, DataE>
export function useAsyncData<DataT, DataE> (
key: MaybeRefOrGetter<string>,
handler: (nuxtApp: NuxtApp, options: { signal: AbortSignal }) => Promise<DataT>,
options?: AsyncDataOptions<DataT>
): Promise<AsyncData<DataT, DataE>>
type AsyncDataOptions<DataT> = {
server?: boolean
lazy?: boolean
immediate?: boolean
deep?: boolean
dedupe?: 'cancel' | 'defer'
default?: () => DataT | Ref<DataT> | null
transform?: (input: DataT) => DataT | Promise<DataT>
pick?: string[]
watch?: MultiWatchSources | false
getCachedData?: (key: string, nuxtApp: NuxtApp, ctx: AsyncDataRequestContext) => DataT | undefined
timeout?: number
}
type AsyncDataRequestContext = {
/** The reason for this data request */
cause: 'initial' | 'refresh:manual' | 'refresh:hook' | 'watch'
}
type AsyncData<DataT, ErrorT> = {
data: Ref<DataT | undefined>
refresh: (opts?: AsyncDataExecuteOptions) => Promise<void>
execute: (opts?: AsyncDataExecuteOptions) => Promise<void>
clear: () => void
error: Ref<ErrorT | undefined>
status: Ref<AsyncDataRequestStatus>
}
interface AsyncDataExecuteOptions {
dedupe?: 'cancel' | 'defer'
timeout?: number
signal?: AbortSignal
}
type AsyncDataRequestStatus = 'idle' | 'pending' | 'success' | 'error'