在项目开发中,进行网络请求目前我们较为常用的是axios,今天进行下封装,封装好处就不多说了
环境我用的是vue cli创建的项目
特点及难点是
1.实现了三种拦截器(全局,axios实例,某个接口)
2.实现接口返回类型
service/index: 在此文件创建axios实例
service/config/index: 配置文件
service/modules: 各个业务模块接口
service/request/index: 对axios封装
service/request/type: 类型声明
service/index
import { BASE_URL, TIME_OUT } from "./config";
import GSRequest from "./request";
// 根据不同配置创建不同axios实例
const gsRequest = new GSRequest({
baseURL: BASE_URL,
timeout: TIME_OUT,
interceptors: {
requestSuccessFn(config) {
// console.log("个别axios instance请求成功拦截");
return config;
},
requestFailureFn(err) {
return err;
},
responseSuccessFn(res) {
return res;
},
responseFailureFn(err) {
return err;
},
},
});
export default gsRequest;
service/config/index
export const BASE_URL = "http://httpbin.org";
export const TIME_OUT = 10000;
service/modules
import gsRequest from "../index";
// gsRequest
// .request({
// url: "/get",
// })
// .then((res) => {
// console.log(res);
// });
interface IPostResType {
json: {
id: string;
name: string;
age: number;
};
origin: string;
url: string;
}
gsRequest
.request({
url: "/post",
method: "post",
data: {
id: "124531",
name: "zhao",
age: 12,
},
interceptors: {
requestSuccessFn(config) {
// console.log("post个别请求拦截成功");
return config;
},
responseSuccessFn(res) {
// console.log("post个别请求响应成功拦截");
return res;
},
},
})
.then((res) => {
console.log(res);
console.log(res.json);
});
gsRequest
.get({
url: "get",
})
.then((res) => {
console.log(res);
});
service/request/index:
/**
* 两个难点:
* 1. 三种拦截器
* 全局拦截器
* 实例拦截器
* 请求拦截器
* 2. 返回结果类型处理<泛型>
*/
import axios from "axios";
import type { AxiosInstance } from "axios";
import { GSRequestConfig } from "./type";
// 用类封装的好处,可以创建多个axios实例
class GSRequest {
instance: AxiosInstance;
constructor(config: GSRequestConfig) {
this.instance = axios.create(config);
// 每个instance都添加拦截器
this.instance.interceptors.request.use(
(config) => {
// loading/token
// console.log("全局请求成功拦截");
return config;
},
(err) => {
// console.log("全局请求失败拦截");
return err;
}
);
this.instance.interceptors.response.use(
(res) => {
// console.log("全局响应成功拦截");
return res.data;
},
(err) => {
// console.log("全局响应失败拦截");
return err;
}
);
// 对单个instance添加拦截器
this.instance.interceptors.request.use(
config.interceptors?.requestSuccessFn,
config.interceptors?.requestFailureFn
);
this.instance.interceptors.response.use(
config.interceptors?.responseSuccessFn,
config.interceptors?.responseFailureFn
);
}
// 封装网络请求方法
// 使用泛型确定返回data的具体类型
request(config: GSRequestConfig) {
// 单个instance中某个请求也可能会有单独拦截器,对config进行处理后重新赋值给config
if (config.interceptors?.requestSuccessFn) {
config = config.interceptors.requestSuccessFn(config);
}
return new Promise((resolve, reject) => {
this.instance
.request(config)
.then((res) => {
// 单个instance中某个请求也可能会有单独拦截器,对res进行处理后重新赋值给res
if (config.interceptors?.responseSuccessFn) {
res = config.interceptors.responseSuccessFn(res);
}
resolve(res);
})
.catch((err) => {
reject(err);
});
});
}
get(config: GSRequestConfig) {
return this.request({ ...config, method: "GET" });
}
post(config: GSRequestConfig) {
return this.request({ ...config, method: "POST" });
}
delete(config: GSRequestConfig) {
return this.request({ ...config, method: "DELETE" });
}
patch(config: GSRequestConfig) {
return this.request({ ...config, method: "PATCH" });
}
}
export default GSRequest;
service/request/type
import { AxiosRequestConfig, AxiosResponse } from "axios";
// 因为我们对返回类型做了泛型处理,所以res不能写死
interface GSInterceptors {
requestSuccessFn?: (config: AxiosRequestConfig) => AxiosRequestConfig;
requestFailureFn?: (err: any) => any;
responseSuccessFn?: (res: T) => T;
responseFailureFn?: (err: any) => any;
}
export interface GSRequestConfig extends AxiosRequestConfig {
interceptors?: GSInterceptors;
}
欢迎交流讨论