Axios 封装(@quiteer/axios)
基于 axios 的 TypeScript 封装,提供类 + Proxy 的使用体验,内置请求拦截、错误提示、撤回/重试、缓存与调试日志插件,适合中大型前端项目统一网络层。
安装
bash
pnpm add @quiteer/axios快速上手
ts
import { createClient, createApi } from '@quiteer/axios'
// 创建基础客户端(可传入 baseURL/timeout/headers 等)
const client = createClient({ baseURL: 'https://api.example.com', timeout: 15000 })
// 直接使用快捷方法
await client.get('/users', { params: { page: 1 } })
// 语义化 API(返回 data,支持泛型推导)
const api = createApi(client)
const list = await api.get<{ items: User[]; total: number }>('/users', {
params: { page: 1 },
contract: d => d.data // 将响应结构映射为需要的数据形态
})核心导出
ts
import {
// 客户端与构建器
AxiosClient, createClient, build,
// 方法层(函数式 API)
createApi,
// 插件体系
createErrorTipsPlugin, createLoadingPlugin, createLoggerPlugin, DebugStore,
// 环境构建
createClientForEnv,
// 重试与类型
RetryStrategy, ExponentialBackoffStrategy,
type AxiosPlugin, type RetryOptions, type RequestExtras
} from '@quiteer/axios'插件与拦截器
ts
import { createClient, createErrorTipsPlugin, createLoadingPlugin, createLoggerPlugin, DebugStore } from '@quiteer/axios'
const store = new DebugStore()
const client = createClient({ baseURL: '...' })
// 错误提示(可通过 config.__silent 关闭单次提示)
client.use(createErrorTipsPlugin({
toast: msg => window.alert(msg),
bizCodeField: 'code',
bizMsgField: 'message',
successCode: 0,
defaultSilent: false
}))
// Loading 状态回调
client.use(createLoadingPlugin((key, active) => {
console.log('loading:', key, active)
}))
// 调试日志(开发环境启用)
client.use(createLoggerPlugin(store))详细参数说明
createClient(defaults):创建带快捷方法的客户端,defaults为 axios 原生配置。build(defaults, setup):统一构建并在setup中注册拦截器/插件。createApi(client):返回语义化Api,方法为:get/post/put/patch/delete/head/options/request/raw/cache。RequestOptions<T>:高阶方法入参。params:查询参数对象data:请求体对象(自动根据Content-Type表单序列化)config:原生 axios 配置extras:请求控制项(见下)contract:(data:any)=>T映射函数,强类型返回loading:{ enabled?: boolean, onChange?: (key, active)=>void }transform:{ filterEmpty?: boolean, dateToISO?: boolean, encrypt?: (obj)=>any, decrypt?: (obj)=>any }
RequestExtras:统一请求控制项。key:请求唯一键(默认method|url|params|data)autoCancel:在发起同键请求前撤回上一个(默认true于语义化 API 中)retry:{ times?: number, strategy?: RetryStrategy, retryOn?: (err)=>boolean }loading:同上silent:静默错误提示cache:{ enabled?: boolean, ttl?: number, key?: string }
- 插件接口
AxiosPlugin:onRequest/onResponse/onError - 重试策略
RetryStrategy与默认ExponentialBackoffStrategy
使用场景
- 列表查询与搜索:启用
autoCancel,避免并发旧请求;开启cache减少重复拉取 - 表单提交流程:
transform.filterEmpty/dateToISO规整负载,contract收敛返回结构 - 错误统一提示:
createErrorTipsPlugin配合业务码与__silent控制静默 - 页面全局 Loading:
createLoadingPlugin将请求维度的 loading 写入全局状态 - 调试与问题定位:
createLoggerPlugin + DebugStore在开发环境采集请求日志 - 稳定性提升:
retry遇到 5xx/超时等网络错误指数退避重试
示例大全
1. GET 列表(自动去重 + 缓存 5s)
ts
import { createApi, build } from '@quiteer/axios'
const client = build({ baseURL: '/api' })
const api = createApi(client)
const list = await api.get<List>('/items', {
params: { q: 'keyword' },
extras: { key: 'items', autoCancel: true, cache: { enabled: true, ttl: 5000 } }
})
// 刷新后清缓存
api.cache.clear('items')2. POST 表单(过滤空值 + 日期转 ISO + 契约返回)
ts
type SubmitResult = { ok: boolean }
await api.post<SubmitResult>('/submit', {
data: formModel,
transform: { filterEmpty: true, dateToISO: true },
contract: d => d.data as SubmitResult,
loading: { enabled: true, onChange: (key, active) => ui.setLoading(active) }
})3. 错误提示(业务码与静默控制)
ts
import { build, createErrorTipsPlugin } from '@quiteer/axios'
const client = build({ baseURL: '/api' }, c => {
c.use(createErrorTipsPlugin({ toast: (msg) => Message.error(msg), successCode: 0 }))
})
// 单次静默
await api.get('/danger', { extras: { silent: true } })4. 重试策略(指数退避)
ts
import { ExponentialBackoffStrategy } from '@quiteer/axios'
await api.get('/unstable', {
extras: { retry: { times: 3, strategy: new ExponentialBackoffStrategy(200, 2000) } }
})5. 多环境与多域名
ts
import { createClientForEnv, createApi } from '@quiteer/axios'
const uploadClient = createClientForEnv({ dev: 'https://dev-upload', prod: 'https://upload' })
const uploadApi = createApi(uploadClient)
await uploadApi.post('/file', { data: file })6. 自定义加密/解密
ts
const encrypt = (obj: any) => AES.encrypt(JSON.stringify(obj))
const decrypt = (cipher: any) => JSON.parse(AES.decrypt(cipher))
await api.post('/secure', {
data: payload,
transform: { encrypt, decrypt }
})TS 类型提示建议
- 为返回体定义类型别名(如
type ApiResponse<T> = { code: number; message: string; data: T }),在contract中统一取data - 在方法层优先传入
contract,避免到处写as any
常见问题
- 与原生 axios 的区别?不暴露原始实例,统一拦截器与插件链;方法层提供强类型与业务契约;额外支持撤回、重试、缓存与日志。
- 如何关闭自动提示?使用
extras.silent: true,或在错误插件配置defaultSilent: true。 - 如何查看请求日志?在开发环境启用
createLoggerPlugin + DebugStore,自行接入 UI 面板。