网络请求也是现在的项目中必不可少的,只要不是玩具代码,基本都需要发送网络请求。本篇文章我们讲解如何基Axios
封装我们项目的网络请求工具,如何管理我们的接口,使得后续我们发送网络请求更加简单易用易维护。

首先明确一下我们本次封装需要做的事:
- 先基于axios封装一个Request请求工具类,这个类支持扩展不同的拦截器
- 通过拦截器去支持请求参数处理,包括参数转换/序列化,支持文件上传
- 通过拦截器支持取消重复请求
- 通过响应错误拦截器支持支持请求重试
- 支持统一的错误码处理
- 支持接口统一的loading/报错提示等
- 接口统一管理,有良好的接口字段提示等
axios简单使用
首先,我们从axios
最简单的用法开始讲起,通常我们如果什么都不封装,就会像如下一样直接使用:
axios.create({}) .request({ url: 'xxx', method: 'POST', data: {}}) .then(res => { // 拿到请求结果 });
这么写倒不是说有什么问题,只不过就不利于管理维护了。
比如说接口异常了,这么写就得每个地方都catch一下,而其实我们希望可以有统一错误处理,然后业务层再根据自己的特定需要去catch,如果不catch,就走默认的统一错误处理。
再比如说要做接口的loading,不统一管理的话,就得每个地方的请求都自己去触发loading和关掉loading。
基于上面的种种需求,所以说统一的请求封装处理是很有必要的。
axios封装
封装Request工具类
首先,我们写一个叫Request
的工具类来保存公共的请求配置和axios实例
export default class Request {// 保存axios实例private axiosInstance: AxiosInstance;// 保存请求公共配置,所有Request实例的请求都共用的这个配置private readonly options: RequestOptions;constructor(options: RequestOptions) {this.options = options;this.axiosInstance = axios.create(options);}// 提供一个方法可以修改当前保存的axios实例setAxios(config: RequestOptions): void {this.axiosInstance = axios.create(config);}getAxios() {return this.axiosInstance;}// 真正的请求方法,其实还是调的axios的request// curRequestOptions是每个请求都可以有自己配置的options,用于覆盖公共的配置request<T = any>(config: AxiosRequestConfig, curRequestOtions?: RequestOptions): Promise<T> {return new Promise((resolve, reject) => {this.axiosInstance.request<T>(config).then((res) => {resolve(res.data);}).catch((error) => {reject(error);});});}get<T = any>(url: string, data: any): Promise<T>;get<T = any>(config: AxiosRequestConfig, curRequestOtions?: RequestOptions): Promise<T>;get(config: string | AxiosRequestConfig, data: any = undefined) {let conf: AxiosRequestConfig = {};let options = undefined;if (typeof config === 'string') {conf.url = config;conf.params = data;} else {conf = config;if (data) {options = data;}}return this.request({ ...conf, method: 'GET' }, options);}post