思路: 创建axios拦截器class类(HttpRequest); 每次发起请求时,new一个HttpRequest(),记录axios请求序列(可在此添加加载loading),并通过vuex记录axios cancelToken; 页面路由切换时,终止已发出的请求,并清空axios请求序列提升系统性能; import axios from "axios"; class HttpRequest { constructor() { this.baseURL = process.env.NODE_ENV === "production" ? "" : "../../"; this.timeout = 3000; // 可根据Object.keys(this.queue).length判断队列中是否还有请求,从而控制loading显示 this.queue = {}; // 专门用来维护请求队列,页面切换需要取消请求 } setInterceptor(instance, url) { instance.interseptors.request.use((config) => { // 开起loading 当序列为空的时候开启loading(第一次进来) if (!Object.keys(this.queue).length) { //开起loading } // 将请求添加值请求队列 this.queue[url] = true; const CancelToken = axios.cancelToken; config.cancelToken = new CancelToken((c) => { console.log("c: ", c); // c 就是当前取消请求都token // 可存到vuex中,当页面切换或者组件销毁的时候调用出来终止请求 // store.commit('set_token', c); // 同步将取消方法存入vuex // 如需清空,可在路由守卫中添加清除逻辑,调L89清空token方法 }); return config; }); instance.interseptors.response.use( (res) => { // 请求一旦相应,则把该请求从请求序列中移除 delete this.queue[url]; //关闭loading 当清空序列的时候关闭loading if (!Object.keys(this.queue).length) { // 关闭loading } // 请求成功处理 if (res.code === 200) { console.log("success", res); return res.data; } else { Promise.reject(res); } }, (err) => { // 请求失败,也需要把该请求从请求序列中移除 delete this.queue[url]; //关闭loading 当清空序列的时候关闭loading if (!Object.keys(this.queue).length) { // 关闭loading } Promise.reject(err); } ); } // 所有请求都经过request方法发起 request(options) { // 每次请求可以创建一个新的实例,如果业务不复杂,可直接使用axios实例 let instance = axios.create(); let config = { baseURL: this.baseURL, timeout: this.timeout, ...options, }; this.setInterceptor(instance, config.url); return instance(config); // 产生的是一个 promise } get(url, data) { return this.request({ url, method: "get", ...data, }); } post(url, data) { return this.request({ url, method: "post", data, }); } } export default new HttpRequest();