vue拦截器配置全局loading

2,666 阅读1分钟

场景: 页面请求时为了提升用户体验,显示加载中的动画提示用户当前正在请求中,当获得请求响应时,结束加载动画,显示加载结果。

如果每次请求都分别设置对应的加载动画,代码会非常冗余,可以利用请求拦截器和响应拦截器,对全局的加载动画进行统一配置。

import Vue from 'vue';
import axios from "axios";
import {
  Message,
  Loading
} from 'element-ui'

let loading;
//开始加载动画
function startLoading() {
  loading = Loading.service({
    lock: true, //是否锁定
    text: '拼命加载中...', //加载中需要显示的文字
    background: 'rgba(0,0,0,.7)', //背景颜色
  });
}
//结束加载动画
function endLoading() {
  loading.close();
}
//需要加载的次数
let needLoadingRequestCount = 0
function showFullScreenLoading() {
  if (needLoadingRequestCount === 0) {
    startLoading()
  }
  needLoadingRequestCount++
}
function tryHideFullScreenLoading() {
  if (needLoadingRequestCount <= 0) return
  needLoadingRequestCount--
  if (needLoadingRequestCount === 0) {
    endLoading()
  }
}

let config = {
  // baseURL: process.env.baseURL || process.env.apiUrl || ""
  // timeout: 60 * 1000, // Timeout
  // withCredentials: true, // Check cross-site Access-Control
};

const _axios = axios.create(config);

//请求拦截器
_axios.interceptors.request.use(
  function (config) {
    showFullScreenLoading()
    //统一添加token
    let token = localStorage.getItem('token');
    if (config.token === true && token != '') {
      config.headers['token'] = localStorage.getItem('token')
    }
    return config;
  },
  function (error) {
    return Promise.reject(error);
  }
);

// 相应拦截器
_axios.interceptors.response.use(
  function (response) {
    //捕获成功的相应
    tryHideFullScreenLoading()
    return response;
  },
  function (error) {
    //捕获失败的相应
    tryHideFullScreenLoading() //如果错误也结束动画
    //如果有错误,捕获并提示错误信息
    if (error.response && error.response.data && error.response.data.errorCode) {
      Message.error(error.response.data.msg)
    }
    return Promise.reject(error);
  }
);

Plugin.install = function (Vue, options) {
  // console.log(options);
  Vue.axios = _axios;
  window.axios = _axios;
  Object.defineProperties(Vue.prototype, {
    axios: {
      get() {
        return _axios;
      }
    },
    $axios: {
      get() {
        return _axios;
      }
    },
  });
};

Vue.use(Plugin)

export default Plugin;

实现的核心在于:

startLoading和endLoading分别用于开始加载动画和结束加载动画

showFullScreenLoading和tryHideFullScreenLoading分别用于合并同一时刻的请求数量

当needLoadingRequestCount=0时开启加载动画,此后如果有请求只需要把needLoadingRequestCount+1,即记录请求数量,但并不启动动画加载;当收到响应时,把needLoadingRequestCount-1,减少请求数量,当needLoadingRequestCount=0,结束加载动画。