Nuxt 中的自定義 useFetch
如何在 Nuxt 中為呼叫外部 API 建立自定義 fetcher。
在使用 Nuxt 時,您可能會在前端呼叫外部 API,並且可能需要為從 API 獲取資料設定一些預設選項。
$fetch
實用函式(由 useFetch
可組合函式使用)故意不支援全域性配置。這很重要,因為這樣可以確保整個應用程式中的資料獲取行為保持一致,並且其他整合(例如模組)可以依賴於 $fetch
等核心實用函式的行為。
然而,Nuxt 提供了一種為您的 API 建立自定義 fetcher 的方法(如果您有多個 API 要呼叫,則可以建立多個 fetcher)。
$fetch
自定義
讓我們使用 Nuxt 外掛建立一個自定義 $fetch
例項。
$fetch
是一個已配置的例項ofetch它支援新增 Nuxt 伺服器的基本 URL 以及在 SSR 期間直接函式呼叫(避免 HTTP 往返)。讓我們假設這裡
- 主 API 是https://api.nuxt.com
- 我們正在使用以下方式將 JWT 令牌儲存在會話中:nuxt-auth-utils
- 如果 API 返回
401
狀態碼,我們會將使用者重定向到/login
頁面。
app/plugins/api.ts
export default defineNuxtPlugin((nuxtApp) => {
const { session } = useUserSession()
const api = $fetch.create({
baseURL: 'https://api.nuxt.com',
onRequest ({ request, options, error }) {
if (session.value?.token) {
// note that this relies on ofetch >= 1.4.0 - you may need to refresh your lockfile
options.headers.set('Authorization', `Bearer ${session.value?.token}`)
}
},
async onResponseError ({ response }) {
if (response.status === 401) {
await nuxtApp.runWithContext(() => navigateTo('/login'))
}
},
})
// Expose to useNuxtApp().$api
return {
provide: {
api,
},
}
})
透過這個 Nuxt 外掛,$api
從 useNuxtApp()
暴露出來,可以直接從 Vue 元件進行 API 呼叫。
app/app.vue
<script setup>
const { $api } = useNuxtApp()
const { data: modules } = await useAsyncData('modules', () => $api('/modules'))
</script>
用
useAsyncData
包裝可避免在進行伺服器端渲染時(伺服器和客戶端在水合時)出現雙重資料獲取。useFetch
/useAsyncData
自定義
現在 $api
包含了我們想要的邏輯,讓我們建立一個 useAPI
可組合函式來替代 useAsyncData
+ $api
的用法。
app/composables/useAPI.ts
import type { UseFetchOptions } from 'nuxt/app'
export function useAPI<T> (
url: string | (() => string),
options?: UseFetchOptions<T>,
) {
return useFetch(url, {
...options,
$fetch: useNuxtApp().$api as typeof $fetch,
})
}
讓我們使用新的可組合函式,並擁有一個美觀整潔的元件。
app/app.vue
<script setup>
const { data: modules } = await useAPI('/modules')
</script>
如果您想自定義返回的任何錯誤的型別,也可以這樣做。
import type { FetchError } from 'ofetch'
import type { UseFetchOptions } from 'nuxt/app'
interface CustomError {
message: string
statusCode: number
}
export function useAPI<T> (
url: string | (() => string),
options?: UseFetchOptions<T>,
) {
return useFetch<T, FetchError<CustomError>>(url, {
...options,
$fetch: useNuxtApp().$api,
})
}
此示例演示瞭如何使用自定義
useFetch
,但對於自定義 useAsyncData
來說,結構是相同的。在 文件 > 4 X > 示例 > 高階 > 使用自定義 Fetch 可組合項中閱讀和編輯即時示例。
我們目前正在討論尋找一種更清晰的方式讓您建立自定義 fetcher,請參閱:https://github.com/nuxt/nuxt/issues/14736.