Nuxt 中的自定义 useFetch
如何在 Nuxt 中创建用于调用你外部 API 的自定义 fetcher。
在使用 Nuxt 时,你可能在开发前端并获取一个外部 API,并且可能想为从你的 API 获取数据设置一些默认选项。
$fetch 工具函数(被 useFetch 组合式函数使用)特意设计为不可全局配置。这一点很重要,这样你应用中的获取行为才能保持一致,其它集成(如模块)才能依赖像 $fetch 这样的核心工具的行为。
不过,Nuxt 提供了一种方式来为你的 API 创建自定义的 fetcher(如果你有多个 API 要调用,也可以创建多个 fetcher)。
配方:带鉴权的 API 客户端
假设你有一个外部 API 在 https://api.nuxt.com,需要通过 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 服务器的 base 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 包裹可以避免在服务端渲染时(服务端与水合时的客户端)重复获取两次数据。