Skip to content

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();

Released under the MIT License.