Appearance
43.Vue 项目中有封装过 axios 吗?主要是封装哪方面的?
- 设置请求超时时间。
- 根据项目环境设置请求路径。
- 设置请求拦截,自动添加 Token。
- 设置响应拦截,对响应的状态码或者数据进行格式化。
- 增添请求队列,实现 loading 效果。
- 维护取消请求 token,在页面切换时通过导航守卫可以取消上个页面中正在发送的请求。
js
class AjaxRequest {
constructor() {
// development production
this.baseURL =
process.env. NODE_ENV !== "production" ? "http://localhost:3000/api" : "/"; // 基础路径
this.timeout = 3000; // 超时时间
this.queue = {};
}
setInterceptor(instance, url) {
instance.interceptors.request.use(
(config) => {
// 每次请求前 将token 放到请求中
config.headers.token = localStorage.getItem("token") || "";
// 每次请求的时候 都拿到一个取消请求的方法
let Cancel = axios.CancelToken; // 产生一个请求令牌
config.cancelToken = new Cancel(function (c) {
store.commit(types.PUSH_TOKEN, c);
});
// 只要页面变化 就要去依次调用cancel方法 路由的钩子 beforeEach
// 显示loading
if (Object.keys(this.queue).length === 0) {
this.toast = Toast.$create({
txt: "正在加载", // 每次显示toast组件时 都叫 正在加载 否则别人把txt的值改了
time: 0,
});
this.toast.show(); // 如果没有请求过 显示loading
}
// 请求前 增加请求队列
this.queue[url] = url; // 存入队列中
return config;
},
(err) => {
return Promise.reject(err);
}
);
instance.interceptors.response.use(
(res) => {
// 响应拦截, 关闭loading
delete this.queue[url];
if (Object.keys(this.queue).length === 0) {
this.toast.hide(); // 当队列被清空隐藏掉即可
}
if (res.data.code === 0) {
return res.data.data;
} else {
return Promise.reject(res.data);
}
},
(err) => {
delete this.queue[url]; // 请求完成后删除对应的url
if (Object.keys(this.queue).length === 0) {
this.toast.hide(); // 当队列被清空隐藏掉即可
}
return Promise.reject(err);
}
);
}
request(options) {
let instance = axios.create();
let config = {
...options,
baseURL: this.baseURL,
timeout: this.timeout,
};
this.setInterceptor(instance, options.url); // 给这个实例增加拦截功能
return instance(config); // 返回的是一个promise
}
}
export default new AjaxRequest();
class AjaxRequest {
constructor() {
// development production
this.baseURL =
process.env. NODE_ENV !== "production" ? "http://localhost:3000/api" : "/"; // 基础路径
this.timeout = 3000; // 超时时间
this.queue = {};
}
setInterceptor(instance, url) {
instance.interceptors.request.use(
(config) => {
// 每次请求前 将token 放到请求中
config.headers.token = localStorage.getItem("token") || "";
// 每次请求的时候 都拿到一个取消请求的方法
let Cancel = axios.CancelToken; // 产生一个请求令牌
config.cancelToken = new Cancel(function (c) {
store.commit(types.PUSH_TOKEN, c);
});
// 只要页面变化 就要去依次调用cancel方法 路由的钩子 beforeEach
// 显示loading
if (Object.keys(this.queue).length === 0) {
this.toast = Toast.$create({
txt: "正在加载", // 每次显示toast组件时 都叫 正在加载 否则别人把txt的值改了
time: 0,
});
this.toast.show(); // 如果没有请求过 显示loading
}
// 请求前 增加请求队列
this.queue[url] = url; // 存入队列中
return config;
},
(err) => {
return Promise.reject(err);
}
);
instance.interceptors.response.use(
(res) => {
// 响应拦截, 关闭loading
delete this.queue[url];
if (Object.keys(this.queue).length === 0) {
this.toast.hide(); // 当队列被清空隐藏掉即可
}
if (res.data.code === 0) {
return res.data.data;
} else {
return Promise.reject(res.data);
}
},
(err) => {
delete this.queue[url]; // 请求完成后删除对应的url
if (Object.keys(this.queue).length === 0) {
this.toast.hide(); // 当队列被清空隐藏掉即可
}
return Promise.reject(err);
}
);
}
request(options) {
let instance = axios.create();
let config = {
...options,
baseURL: this.baseURL,
timeout: this.timeout,
};
this.setInterceptor(instance, options.url); // 给这个实例增加拦截功能
return instance(config); // 返回的是一个promise
}
}
export default new AjaxRequest();