在 Nuxt 中自定义 useFetch

如何创建一个自定义的 fetcher 来在 Nuxt 中调用外部 API。

在使用 Nuxt 开发时,你可能需要编写前端并获取外部 API,并且你可能希望为调用 API 设置一些默认选项。

$fetch 工具函数(由 useFetch 可组合函数使用)被刻意设计为不可全局配置。这一点非常重要,因为它可以确保整个应用程序中的数据获取行为保持一致,并且其他集成(如模块)可以依赖像 $fetch 这样的核心工具的行为。

不过,Nuxt 提供了一种为你的 API 创建自定义 fetcher 的方法(如果你有多个 API 需要调用,也可以创建多个 fetcher)。

配方:带认证的 API 客户端

假设你有一个位于 https://api.nuxt.com 的外部 API,它需要通过以下方式进行 JWT 认证:nuxt-auth-utils,并且你希望在收到 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>
更多信息请阅读 文档 > 4 X > API > Composables > Create Use Fetch

配方:自定义 $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 包裹请求,可以避免在服务器端渲染(SSR)时出现重复数据获取(服务器渲染及客户端水合时)。