vue+element+axios 通过拦截器实现的全局loading加载动画

16 篇文章 2 订阅

一、定义全局变量 请求动画、请求数量、请求动画白名单

// 请求动画
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() 方法

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

爱宇阳

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值