vue+element+axios 通過攔截器實現的全局loading加載動畫

一、定義全局變量 請求動畫、請求數量、請求動畫白名單

// 請求動畫
let oLoadingAnimation;
// 請求數量
let nNumberOfRequests = 0;
// 請求動畫白名單
const aLoadingWhiteList = [];

二、 封裝開始動畫、結束動畫

import { Loading } from "element-ui";

/**
 * 開始動畫
 */
function sLoadingAnimation() {
  // 如果請求數量等於 0,則開始動畫
  if (nNumberOfRequests === 0) {
    oLoadingAnimation = Loading.service({
      lock: true,
      text: "加載中...",
      background: "#ffffff"
    });
  }
  // 請求數量++
  nNumberOfRequests++;
}

/**
 * 結束動畫
 */
function eLoadingAnimation() {
  // 請求數量--
  nNumberOfRequests--;
  // 如果請求數量小於等於 0,則結束動畫
  if (nNumberOfRequests <= 0) {
    oLoadingAnimation.close();
  }
}

三、使用動畫

// 請求攔截器開始動畫
// 開始動畫
if (aLoadingWhiteList.indexOf(config.url) === -1) {
  sLoadingAnimation();
}


// 響應攔截器結束動畫
// 結束動畫
if (aLoadingWhiteList.indexOf(res.config.url) === -1) {
  eLoadingAnimation();
}

 四、封裝接口請求文件

注:這是本人根據項目寫的封裝文件,使用前請自己的項目做出對應調整

/*
 * Copyright © 2019-2020 LiuDanYang/LiJia. All rights Reserved.
 */

import axios from "axios";
import { MessageBox, Message, Loading } from "element-ui";
import store from "@/store";
import { getToken } from "@u/auth";

// 請求動畫
let oLoadingAnimation;
// 請求數量
let nNumberOfRequests = 0;
// 請求動畫白名單
const aLoadingWhiteList = [
  "/cart/view",
  "/cart/add",
  "/cart/remove",
  "/goods/acquire-search-history",
  "/config/read",
  "/user-goods",
  "/user-goods/cancel-fav",
  "/user-merchants",
  "/user-merchant/cancel-fav",
  "/merchant/add-status",
  "/merchant/phonenumber-vali"
];

/**
 * 創建 axios 實例
 */
const service = axios.create({
  baseURL: process.env.VUE_APP_BASE_API, // url = base url + request url
  // withCredentials: true, // 跨域請求時發送 Cookie
  timeout: 30000, // 請求超時時間
  headers: {
    "Content-Type": "application/json;q=1.0,*/*;q=0.1",
    "X-Api-Type": "PC"
  }
});

/**
 * 請求攔截器,支持添加多個攔截器
 * 例如: 配置 token 、添加一些默認的參數
 * `return config` 繼續發送請求
 */
service.interceptors.request.use(
  config => {
    // 讓每個請求都帶有令牌,['X-Token'] 是自定義標題鍵,請根據實際情況進行修改
    getToken() && (config.headers["XL-Api-Key"] = getToken());

    //開始動畫
    if (aLoadingWhiteList.indexOf(config.url) === -1) {
      sLoadingAnimation();
    }

    return config;
  },
  error => {
    console.log(error);
    return Promise.reject(error);
  }
);

/**
 * 響應攔截器, 支持添加多個攔截器
 * 例如: 根據狀態碼選擇性攔截、過濾轉換數據
 */
service.interceptors.response.use(
  res => {
    const {
      data,
      status,
      data: { status: resStatus, data: resData },
      config: { url, method, data: cData, headers },
      data: rData,
      headers: rHeader
    } = res;

    console.log("-----------------------接口請求開始------------------------");
    console.log(`接口地址:`, url);
    console.log(`接口請求方式:`, method);
    console.log(`接口請求參數:`, cData);
    console.log(`接口請求頭:`, headers);
    console.log(`接口響應數據:`, rData);
    console.log(`接口響應頭:`, rHeader);
    console.log("-----------------------接口請求結束------------------------");

    // 結束動畫
    if (aLoadingWhiteList.indexOf(res.config.url) === -1) {
      eLoadingAnimation();
    }

    // 根據 status 狀態攔截
    switch (status) {
      case 200:
        if (resStatus === "0") {
          msg(resData || "接口錯誤");
          return Promise.reject(resData || "接口錯誤");
        }
        return data;
      case 400:
        msg(resData || "請求錯誤");
        return Promise.reject(new Error(resData || "請求錯誤"));
      case 401:
        reLogin();
        return Promise.reject(new Error(resData || "請求未授權"));
      case 403:
        msg(resData || "拒絕請求");
        return Promise.reject(new Error(resData || "拒絕請求"));
      case 500:
        msg(resData || "服務器錯誤");
        return Promise.reject(new Error(resData || "服務器錯誤"));
      default:
        return Promise.reject(res);
    }
  },
  error => {
    msg(error);
    return Promise.reject(error);
  }
);

/**
 * 開始動畫
 */
function sLoadingAnimation() {
  // 如果請求數量等於 0,則開始動畫
  if (nNumberOfRequests === 0) {
    oLoadingAnimation = Loading.service({
      lock: true,
      text: "加載中...",
      background: "#ffffff"
    });
  }
  // 請求數量++
  nNumberOfRequests++;
}

/**
 * 結束動畫
 */
function eLoadingAnimation() {
  // 請求數量--
  nNumberOfRequests--;
  // 如果請求數量小於等於 0,則結束動畫
  if (nNumberOfRequests <= 0) {
    oLoadingAnimation.close();
  }
}

/**
 * 統一請求提示
 * @param str {String} 提示信息
 */
function msg(str) {
  Message({
    message: str,
    type: "error",
    duration: 2 * 1000
  });
}

/**
 * 重新登錄
 */
function reLogin() {
  MessageBox.confirm("登錄失效,可以取消停留在此頁面上,或者再次登錄", "提示", {
    confirmButtonText: "重新登錄",
    cancelButtonText: "取消",
    type: "warning"
  }).then(() => {
    store.dispatch("user/resetToken").then(() => {
      location.reload();
    });
  });
}

export default service;

 

參考:element Loadingaxios 攔截器JavaScript indexOf() 方法

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章