一、场景描述
为什么要对axios网络请求进行二次封装?
解决代码的复用,提高可维护性。 —这个有两个方案:一个是二次封装一个是实例化。(设置一些公共的参数,然后进行请求)
为什么可以解决代码的复用:
这是最简单格式的代码,需要定义url和请求方式。
axios({
method: "get",
url: "http://codercba.com:9002/banner",
}).then(function (response) {
console.log(response);
}).catch(function (error) {
console.log(error);
});
封装之后的请求方式,减少了点代码
hyRequest.get({ url: "/banner" }).then((res) => {
console.log(res);
setImg(res.banners);
console.log(img);
});
Axios实例化的输出
const instance = axios.create({
baseURL: "http://codercba.com:9002",
});
instance.get("banner").then((response) => {
console.log("实例化请求输出");
console.log(response);
});
二、二次封装的代码实现
type.ts //定义一些类型
import type {
InternalAxiosRequestConfig,
AxiosRequestConfig,
AxiosResponse,
AxiosRequestHeaders,
} from "axios";
export interface HYInterceptors<T = AxiosResponse> { //定义拦截器类型
requestSuccessFn?: (
config: InternalAxiosRequestConfig
) => InternalAxiosRequestConfig;
requestFailureFn?: (err: any) => any;
responseSuccessFn?: (res: T) => T;
responseFailureFn?: (err: any) => any;
}
export interface HYRequestConfig<T = AxiosResponse> extends AxiosRequestConfig { //定义请求体的配置
interceptors?: HYInterceptors<T>;
headers?: AxiosRequestHeaders;
}
request.ts //封装axios
import axios, { InternalAxiosRequestConfig } from "axios";
import type { AxiosInstance } from "axios";
import type { HYRequestConfig } from "./type";
class HYRequest {
instance: AxiosInstance; //实例
constructor(config: HYRequestConfig) {
this.instance = axios.create(config); //实例化axios
this.instance.interceptors.response.use(
(config) => {
return config;
},
(err) => {
return err;
}
);
this.instance.interceptors.response.use(
(res) => {
return res.data;
},
(err) => {
return err;
}
);
this.instance.interceptors.request.use(
config.interceptors?.requestSuccessFn,
config.interceptors?.requestFailureFn
);
this.instance.interceptors.response.use(
config.interceptors?.responseSuccessFn,
config.interceptors?.responseFailureFn
);
}
request<T = any>(config: HYRequestConfig<T>) {
if (config.interceptors?.requestSuccessFn) {
config = config.interceptors.requestSuccessFn(
config as InternalAxiosRequestConfig
);
}
return new Promise<T>((resolve, reject) => {
this.instance //实例请求
.request<any, T>(config)
.then((res) => {
if (config.interceptors?.responseSuccessFn) {
res = config.interceptors.responseSuccessFn(res);
}
resolve(res);
})
.catch((err) => {
reject(err);
});
});
}
get<T = any>(config: HYRequestConfig<T>) {
return this.request({ ...config, method: "GET" });
}
post<T = any>(config: HYRequestConfig<T>) {
return this.request({ ...config, method: "POST" });
}
delete<T = any>(config: HYRequestConfig<T>) {
return this.request({ ...config, method: "DELETE" });
}
patch<T = any>(config: HYRequestConfig<T>) {
return this.request({ ...config, method: "PATCH" });
}
}
export default HYRequest;
index.ts //实例化
import { BASE_URL, TIME_OUT } from "./config";
import HYRequest from "./request";
const hyRequest = new HYRequest({
baseURL: BASE_URL,
timeout: TIME_OUT,
interceptors: {
requestSuccessFn: (config) => {
return config;
},
},
});
export default hyRequest;
可以看到其实封装也是先实例化之后再进行封装。为什么要这么做,实例化的东西不太好维护。包括对拦截器的更新。
三、axios相关内容