$api
由 api.factory 插件创建的增强型 $fetch 实例,支持认证注入、数据解包、业务检查和多端点切换。
介绍
$api 是通过 Nuxt 插件注入的全局 $fetch 实例,内置完整的拦截器链(认证注入、业务状态码检查、数据解包、Toast 提示)。它是所有 API composable(useApiFetch、useLazyApiFetch 等)的底层引擎。
基础用法
const { $api } = useNuxtApp()
// GET 请求(数据已自动解包)
const users = await $api<User[]>('/users')
// POST 请求
const user = await $api<User>('/users', {
method: 'POST',
body: { name: 'test', email: 'test@example.com' }
})
// PUT 请求
const updated = await $api<User>(`/users/${id}`, {
method: 'PUT',
body: { name: 'new-name' }
})
// DELETE 请求
await $api(`/users/${id}`, { method: 'DELETE' })
$api 返回的数据已经过拦截器自动解包(提取 dataKey 字段),泛型 T 直接对应业务数据类型。多端点切换
使用 $api.use(endpoint) 切换到指定端点:
const { $api } = useNuxtApp()
// 使用默认端点
const users = await $api('/users')
// 切换到 admin 端点
const adminUsers = await $api.use('admin')('/users')
// 保存端点引用,避免重复 use()
const adminApi = $api.use('admin')
const config = await adminApi('/config')
const stats = await adminApi('/stats')
端点实例内部有缓存机制,多次调用 $api.use('admin') 返回同一实例。
在事件处理器中使用
事件处理器中使用 $api 是最常见的场景:
<script setup lang="ts">
const { $api } = useNuxtApp()
// 表单提交
async function handleCreate(formData: CreateUserRequest) {
try {
const user = await $api<User>('/users', {
method: 'POST',
body: formData
})
// Toast 已自动显示,无需手动处理
navigateTo(`/users/${user.id}`)
}
catch (error) {
// 业务错误 Toast 已自动显示
// 此处可做额外逻辑(如表单字段高亮)
}
}
// 删除确认
async function handleDelete(id: string) {
await $api(`/users/${id}`, { method: 'DELETE' })
await refreshNuxtData() // 刷新页面缓存数据
}
</script>
在 useAsyncData 中使用
当需要聚合多个接口或做复杂数据处理时,在 useAsyncData 中使用 $api:
const { $api } = useNuxtApp()
// 聚合多个接口
const { data: dashboard } = await useAsyncData('dashboard', async () => {
const [users, stats, recent] = await Promise.all([
$api<User[]>('/users'),
$api<Stats>('/stats'),
$api<Activity[]>('/activity/recent')
])
return { users, stats, recent }
})
封装自定义 composable
composables/useDashboard.ts
export function useDashboard() {
const { $api } = useNuxtApp()
return useAsyncData('dashboard', async () => {
const [users, stats] = await Promise.all([
$api<User[]>('/users'),
$api<Stats>('/stats')
])
return { users, stats }
})
}
业务操作 composable
对于删除、审批等写操作,将 $api 调用封装到独立的 composable 中,保持页面文件精简:
composables/useUserActions.ts
export function useUserActions() {
const { $api } = useNuxtApp()
async function remove(id: string) {
await $api(`/users/${id}`, { method: 'DELETE' })
await refreshNuxtData()
}
async function create(data: CreateUserRequest) {
return await $api<User>('/users', {
method: 'POST',
body: data,
})
}
async function updateRole(id: string, role: UserRole) {
return await $api<User>(`/users/${id}/role`, {
method: 'PUT',
body: { role },
context: { toast: { successMessage: '角色已更新' } },
})
}
return { remove, create, updateRole }
}
pages/users/index.vue
<script setup lang="ts">
// 数据获取用 useApiFetch
const { data: users, refresh } = await useApiFetch<User[]>('/users')
// 写操作用 $api composable
const { remove, updateRole } = useUserActions()
</script>
请求级配置
通过 context 字段传递请求级配置:
const { $api } = useNuxtApp()
// 禁用 Toast
await $api('/users', {
context: { toast: false }
})
// 自定义 Toast 消息
await $api('/users', {
method: 'POST',
body: formData,
context: {
toast: { successMessage: '创建成功' }
}
})
// 跳过业务状态码检查(直接返回原始解包数据)
const raw = await $api('/external-api/data', {
context: { skipBusinessCheck: true }
})
context 字段通过 ofetch 的 FetchOptions 扩展传递,仅 Movk Nuxt 的 $api 实例识别此字段。原生 $fetch 不会处理这些选项。API
ApiInstance
$api 的类型定义:
type ApiInstance = $Fetch & {
use: (endpoint: string) => ApiInstance
}
$api(url, options)
Promise<T>
发送 API 请求。支持所有 ofetch 的选项,额外支持
context 字段。$api.use(endpoint)
ApiInstance
切换到指定端点,返回该端点的
$api 实例。端点实例内部有缓存,多次调用返回同一实例。ApiFetchContext
通过 options.context 传递的扩展配置:
toast
RequestToastOptions | false
Toast 提示配置。设为
false 禁用所有 Toast。skipBusinessCheck
boolean
跳过业务状态码检查。设为
true 时不抛出 ApiError,但仍会解包 dataKey 字段。