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 操作,因為這可能會導致意外行為。請遵循此指南以獲取有關如何建立自定義非同步資料獲取器的更多資訊。
datastatuserror 都是 Vue ref,在 <script setup> 中使用時應透過 .value 訪問,而 refresh/executeclear 則是普通函式。

監聽引數

內建的 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
更多資訊請閱讀 文件 > 4.X > 入門 > 資料獲取#useasyncdata

引數

  • key:一個唯一的鍵,用於確保資料獲取可以跨請求正確地去重。如果您不提供鍵,Nuxt 將為 useAsyncData 例項生成一個基於檔名和行號的唯一鍵。
  • handler:一個非同步函式,必須返回一個真值(例如,它不應該是 undefinednull),否則請求可能會在客戶端重複。
    handler 函式應**無副作用**,以確保 SSR 和 CSR 水合期間的可預測行為。如果您需要觸發副作用,請使用 callOnce 工具來實現。
  • options:
    • server:是否在伺服器上獲取資料(預設為 true
    • lazy:是否在載入路由後解析非同步函式,而不是阻塞客戶端導航(預設為 false
    • immediate:設定為 false 時,將阻止請求立即觸發。(預設為 true
    • default:一個工廠函式,用於在非同步函式解析之前設定 data 的預設值 - 與 lazy: trueimmediate: false 選項結合使用時很有用
    • transform:一個函式,可用於在解析後修改 handler 函式的結果
    • getCachedData:提供一個返回快取資料的函式。返回 nullundefined 將觸發一次獲取。預設情況下,這是
      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 並實現載入狀態,以獲得更流暢的使用者體驗。
您可以使用 useLazyAsyncData 來獲得與 useAsyncData 配合 lazy: true 相同的行為。

共享狀態和選項一致性

當多個 useAsyncData 呼叫使用相同的鍵時,它們將共享相同的 dataerrorstatus 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 useAsyncDatadata<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'
文件 > 4 X > 入門 > 資料獲取中閱讀更多資訊。