封装axios二方包

前言

在前端项目开发中,直接使用 axios 发起网络请求虽然简单高效,但在大型项目或多项目协作中存在维护性差、重复代码多等问题。因此,二次封装axios的二方包是有必要的

功能需求

1. 统一请求配置

通过封装可以设置全局默认配置(如超时时间、基础路径、请求头等),避免每个项目都手动重复设置。

2. 拦截器统一管理

封装后可以集中管理请求和响应拦截器,实现通用逻辑(如错误统一处理等)

3. 接口返回格式标准化

封装可统一处理响应数据结构,确保所有接口返回的数据格式一致,便于业务层消费

4. 支持多个项目的复用

将封装后的工具打包插件,可在多个项目中复用,减少重复开发工作。

5. 增强可维护性和扩展性

当需要升级功能或者变更统一逻辑时,只需修改封装层,无需改动业务代码,降低耦合度。

6. 统一错误处理机制

可在封装中统一处理网络异常、业务错误码(如 401、500),并提供友好提示或自动重试机制。

7. 提升开发体验

封装后对外暴露简洁的 API,如 get, post 方法,让开发者更专注于业务逻辑而非底层请求细节。

功能设计

1.类接口设计

封装一个接口类,包含一个构造函数constructor(options: RequestClientOptions = {})

初始化Axios实例时可以传入一些配置参数,比如timeout超时时间、baseUrl,或是拦截器等

2.主要成员变量
instance AxiosInstance Axios实例
addRequestInterceptor Function 自定义添加的请求拦截
addResponseInterceptor Function 自定义添加的相应拦截
requestConfig 记录config配置
download Function 通过一个单独的类生成文件下载方法
upload Function 通过一个单独的类生成文件上传方法
loading boolean 记录是否需要展示loading加载状态
3.默认的全局配置

在constructor中有个defaultConfig以便不用过多配置,如下

js 复制代码
class RequestClient {
    constructor(options: RequestClientOptions = {}) {
        const defaultConfig: RequestClientOptions = {
          headers: {
            'Content-Type': 'application/json;charset=utf-8',
          },
          responseReturn: 'raw',
          // 默认超时时间
          timeout: 10000,
        };
    }
}
4.请求参数处理

初始化对axios的配置参数paramsSerializer做处理,支持自定义参数序列化方式,也可以使用默认值

5.默认的全局拦截

在内部会定义默认的全局请求拦截和响应拦截,譬如处理请求时的页面加载loading,处理通用场景下异常status:403,500等状态码异常错误提示等(支持配置)

6.通用请求工具函数

封装通用请求工具函数request,并支持自定义或默认响应泛型供用户消费,并根据request进一步封装get,post,delete,put/patch供使用

js 复制代码
type ResponseType<T = any> = {
    data: T
    code: number
    message: string
}
type RequestMethods = Extract<
  Method,
  'get' | 'post' | 'put' | 'delete' | 'patch' | 'option' | 'head'
>

public async request<T = ResponseType>(
    method: RequestMethods
    url: string,
    config: RequestClientConfig,
): Promise<AxiosResponse<T>> {
...
}
7.取消请求

部分场景下存在接口需主动取消请求,如tab切换过程中存在接口未响应的,在切换后不需要请求时取消请求,避免存在接口排队的情况

类设计图

classDiagram class RequestClient { +_instance: AxiosInstance +_clientConfig: RequestClientOptions +_interceptorsConfig: InterceptorsConfig +addRequestInterceptor: Function +addResponseInterceptor: Function +upload: Function +download: Function +downloadByPost: Function +downloadByBlob: Function +downloadByBlobPost: Function +requestControllers: Map +request(method, url, config?: RequestClientConfig): Promise +get(url, config?: RequestClientConfig): Promise +post(url, data?, config?: RequestClientConfig): Promise +put(url, data?, config?: RequestClientConfig): Promise +patch(url, data?, config?: RequestClientConfig): Promise +delete(url, param?, config?: RequestClientConfig): Promise +initSuccessCodes(successCodes: number | number[] | undefined | null): Array +initRequestInterceptor(): void +initResponseInterceptor(): void +addRequestController(key): void +removeRequestController(key): void +cancelRequest(key, message?): void +cancelAllRequests(message?): void } class FileDownloader { +client: RequestClient +notification: NotificationConfig +message: MessageConfig +download(url, config): Promise +downloadByPost(url, data, config): Promise +downloadByBlob(url, config): Promise +downloadByBlobPost(url, data, config): Promise } class FileUploader { +client: RequestClient +upload(url, data, config)?: Promise } class Interceptormanager { +instance: AxiosInstance +addRequestInterceptor() RequestInterceptorConfig +addResponseInterceptor() ResponseInterceptorConfig } RequestClient --> FileDownloader : 依赖 RequestClient --> FileUploader : 依赖 RequestClient --> Interceptormanager : 依赖
使用设计
  1. 实例初始化
js 复制代码
// 使用默认
const  http = new RequestClient()
// 添加配置项
const  http = new RequestClient(
    config: RequestClientOptions
)

2.自定义config配置

首先config的类型是RequestClientOptions,他继承自AxiosRequestConfig,并在其基础上增加了一些其他的配置属性,譬如paramsSerializer指定序列化,interceptors初始化时指定业务的自定义拦截器等

或是初始化完成之后通过调用实例中的addRequestIntercepter或addResponseIntercepter去给axios实例的interceptors添加拦截器处理

  1. 业务代码使用
csharp 复制代码
// api接口,如module=user
const http = new RequestClient()
// 1. 直接使用request方法
const _userInfo = (params) => {
    return  http.request<ResponseType>('get', url, {params})
}
// 2.使用具体的方法
const _userInfo = (params) => {
    return  http.get<ResponseType>( url, {params})
}

这里的DataType是接口返回的data中数据类型,方便提示

调用流程图
相关推荐
一斤代码5 小时前
vue3 下载图片(标签内容可转图)
前端·javascript·vue
中微子5 小时前
React Router 源码深度剖析解决面试中的深层次问题
前端·react.js
光影少年5 小时前
从前端转go开发的学习路线
前端·学习·golang
中微子6 小时前
React Router 面试指南:从基础到实战
前端·react.js·前端框架
3Katrina6 小时前
深入理解 useLayoutEffect:解决 UI "闪烁"问题的利器
前端·javascript·面试
前端_学习之路7 小时前
React--Fiber 架构
前端·react.js·架构
伍哥的传说7 小时前
React 实现五子棋人机对战小游戏
前端·javascript·react.js·前端框架·node.js·ecmascript·js
qq_424409197 小时前
uniapp的app项目,某个页面长时间无操作,返回首页
前端·vue.js·uni-app
我在北京coding7 小时前
element el-table渲染二维对象数组
前端·javascript·vue.js
布兰妮甜7 小时前
Vue+ElementUI聊天室开发指南
前端·javascript·vue.js·elementui