Nuxt 3 已于 31 July 2026 结束生命周期
此版本将不再接收错误修复或安全补丁。 升级到 Nuxt 4 或获取 HeroDevs 提供的延长支持
Nuxt 中的自定义 useFetch
如何在 Nuxt 中创建调用外部 API 的自定义 fetcher。
Geprüfte Übersetzung ·0 % geprüft
使用 Nuxt 时,你可能正在构建前端并调用外部 API,或者想为 API 调用设置一些默认的 fetch 选项。
$fetch 工具函数(由 useFetch 组合式函数使用)有意不支持全局配置。这一点很重要,这样可以确保应用中的 fetch 行为保持一致,并且其他集成(如模块)可以依赖 $fetch 等核心工具的行为。
不过,Nuxt 提供了一种方法,允许你为 API 创建自定义 fetcher(如果有多个 API 需要调用,也可以创建多个 fetcher)。
自定义 $fetch
让我们使用 Nuxt 插件创建一个自定义的 $fetch 实例。
$fetch 是配置过的 ofetch 实例,支持自动添加你的 Nuxt 服务器的基础 URL,并且在 SSR 阶段直接进行函数调用,从而避免 HTTP 网络往返。假设:
- 主 API 是 https://api.nuxt.com
- 我们使用 nuxt-auth-utils 在 session 中存储 JWT token
- 如果 API 返回
401状态码,我们就将用户重定向到/login页面
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) {
// 注意:这依赖于 ofetch >= 1.4.0 - 你可能需要刷新锁文件
options.headers.set('Authorization', `Bearer ${session.value?.token}`)
}
},
async onResponseError ({ response }) {
if (response.status === 401) {
await nuxtApp.runWithContext(() => navigateTo('/login'))
}
},
})
// 通过 useNuxtApp().$api 暴露
return {
provide: {
api,
},
}
})使用这个 Nuxt 插件后,$api 会在 useNuxtApp() 中暴露,方便你直接在 Vue 组件里调用 API:
app.vue
<script setup>
const { $api } = useNuxtApp()
const { data: modules } = await useAsyncData('modules', () => $api('/modules'))
</script>使用
useAsyncData 包装,可以避免在服务端渲染期间重复获取数据(服务器端和客户端 hydration 时)。自定义 useFetch/useAsyncData
既然 $api 已包含我们期望的逻辑,让我们构建一个 useAPI 组合式函数,用来替代原本 useAsyncData + $api 的用法:
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.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
status: number
}
export function useAPI<T> (
url: string | (() => string),
options?: UseFetchOptions<T>,
) {
return useFetch<T, FetchError<CustomError>>(url, {
...options,
$fetch: useNuxtApp().$api,
})
}此示例展示了如何使用自定义的
useFetch,自定义 useAsyncData 的结构完全相同。 Read and edit a live example in Docs > Examples > Advanced > Use Custom Fetch Composable.
我们目前正在讨论一种更简洁的方式,让你能够创建自定义 fetcher,详见:https://github.com/nuxt/nuxt/issues/14736。