在 Nuxt 中自定义 useFetch
如何在 Nuxt 中为调用外部 API 创建自定义的 fetcher。
当使用 Nuxt 时,你可能在构建前端并从外部 API 获取数据,你可能希望为从你的 API 获取数据设置一些默认选项。
$fetch 工具函数(由 useFetch 组合式函数使用)是刻意不可全局配置的。这一点很重要,以便应用中各处的获取行为保持一致,并且其他集成(如模块)可以依赖核心工具(如 $fetch)的行为。
然而,Nuxt 提供了一种方法,允许为你的 API 创建自定义的 fetcher(如果你有多个要调用的 API,也可以创建多个 fetcher)。
配方:带认证的 API 客户端
假设你在 https://api.nuxt.com 有一个外部 API,它通过 nuxt-auth-utils 使用 JWT 认证,并且你希望在收到 401 响应时重定向到 /login。
app/composables/useAPI.ts
export const useAPI = createUseFetch({
baseURL: 'https://api.nuxt.com',
onRequest ({ options }) {
const { session } = useUserSession()
if (session.value?.token) {
options.headers.set('Authorization', `Bearer ${session.value.token}`)
}
},
async onResponseError ({ response }) {
if (response.status === 401) {
await navigateTo('/login')
}
},
})
现在,每次调用 useAPI 都会自动包含认证请求头并处理 401 重定向:
app/pages/dashboard.vue
<script setup lang="ts">
const { data: profile } = await useAPI('/me')
const { data: orders } = await useAPI('/orders')
</script>
配方:自定义 $fetch 实例
如果你需要更底层的控制,你可以通过 Nuxt 插件 创建一个自定义的 $fetch 实例,然后直接与 useAsyncData 一起使用,或传递给 createUseFetch。
$fetch 是 ofetch 的一个已配置实例,它支持添加 Nuxt 服务的基础 URL 以及在 SSR 期间直接函数调用(避免 HTTP 往返)。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) {
options.headers.set('Authorization', `Bearer ${session.value?.token}`)
}
},
async onResponseError ({ response }) {
if (response.status === 401) {
await nuxtApp.runWithContext(() => navigateTo('/login'))
}
},
})
return {
provide: {
api,
},
}
})
然后你可以直接使用自定义的 $fetch 实例:
app/app.vue
<script setup>
const { $api } = useNuxtApp()
const { data: modules } = await useAsyncData('modules', () => $api('/modules'))
</script>
用
useAsyncData包裹可以避免在服务器端渲染(server & client 在 hydration 时)发生双重数据获取。 Read and edit a live example in Docs > 4 X > Examples > Advanced > Use Custom Fetch Composable.