vue axios—全局loading--------token and refreshToken

 1.在store文件下

//在store/modules/app.js文件里

const state = {
  isShowLoading: false // 控制页面是否正在显示loading
};
const mutations = {

  SET_SHOWLOADING:(state, data)=>{
    state.isShowLoading = data;
  }

}

const actions = {
  setShowloading({ commit }, isShowLoading) {
    commit("SET_SHOWLOADING", isShowLoading);
  }
}


export default {
  state,
  mutations,
  actions,
};

//在store/getters.js文件里
const getters = {
  isShowLoading: state => state.app.isShowLoading,
};
export default getters;

//在store/index.js文件里
import Vue from "vue";
import Vuex from "vuex";
import getters from "./getters";
import app from "./modules/app";
import settings from "./modules/settings";
import user from "./modules/user";

Vue.use(Vuex);

const store = new Vuex.Store({
  modules: {
    app,
  },
  getters,
});

export default store;

 2.axios 请求模块

 

 

import axios from "axios";
import { Message } from "element-ui";
import store from "@/store";
import { setToken, setRefreshToken, getToken, getRefreshToken, removeRefreshToken, removeToken, removeUserInfo } from "@/utils/auth";
import { myI18n } from "@/lang";
// 根据不同的状态码,生成不同的提示信息
const showStatus = (status) => {
  let message = "";
  // 这一坨代码可以使用策略模式进行优化
  switch (status) {
    case "50001":
      message = myI18n("code_50001", "货架已被占用");
      break;
    case "50002":
      message = myI18n("code_50002", "商品已被占用");
      break;
    default:
      message = `${status}`;
  }
  return `${message}`;
};
let loadingCount = 0
const addLoading = () => {
  // 开始请求时,添加数量,并且设置为显示loading
  loadingCount++;
  store.dispatch("app/setShowloading", true);
};
const isCloseLoading = () => {
  // 请求完成或者请求失败时,减少正在请求的数量,并且判断是否还有未完成的请求,如果没有了,则设置为隐藏loading
  loadingCount--;
  if (loadingCount === 0) {
    store.dispatch("app/setShowloading", false);
  }
};


// create an axios instance
const service = axios.create({
  baseURL: process.env.VUE_APP_BASE_API,
  timeout: 5000,
});

// request interceptor
service.interceptors.request.use(
  config => {

    // do something before request is sent
    const noAuthUrls = ["/login", "/refreshToken", '/sso/login'];
    if (!noAuthUrls.includes(config.url)) {
      if (store.getters.token) {
        config.headers["Authorization"] = "Bearer" + " " + getToken();
      }
    }
    addLoading()
    return config;
  },
  error => {
    isCloseLoading()

    // do something with request error
    return Promise.reject(error);
  },
);

// response interceptor
service.interceptors.response.use(
  /**
   * If you want to get http information such as headers or status
   * Please return  response => response
  */

  /**
   * Determine the request status by custom code
   * Here is just an example
   * You can also judge the status by HTTP Status Code
   */
  response => {
    const res = response?.data;
    const res_url = response?.config?.url;
    let msg = "";
    isCloseLoading()
    // if the custom code is not 20000, it is judged as an error.
    if (res.msg !== "SUCCESS") {
      if (response?.config?.url?.indexOf("files/upload") < 0) {
        msg = showStatus(res?.data);
        Message({
          message: msg || "Error",
          type: "error",
          duration: 5 * 1000,
        });
      }
      return Promise.reject(new Error(res.msg || "Error"));
    } else {
      return res;
    }
  },
  async error => {
    var str_error = JSON.stringify(error);
    if (error?.response?.status === 401) {
      if (getRefreshToken()) {
        try {
          const res = await axios.post(process.env.VUE_APP_BASE_API + '/refreshToken', { refresh_token: getRefreshToken(), client_id: 'magic-mirror-security-client-id' })
          const data = res.data.data
          store.dispatch('user/setToken', data.access_token);
          setToken(data.access_token)
          setRefreshToken(data.refresh_token)
          isCloseLoading()
          return service(error.config)
        } catch (error) {
          isCloseLoading()
          removeRefreshToken()
          removeToken()
          removeUserInfo()
          sessionStorage.clear()
          const locals = `${window.location.origin}/#/login`
          window.location.href = locals
          return Promise.reject(error)
        }
      }
    } else if (error?.response?.status === 500) {
      if (error.response.config.url == "/api/login") {
        const msg = myI18n("loginfail", "用户名或密码错误");
        Message({
          message: msg || "USERNAME OR PASSWORD ERROR",
          type: "error",
          duration: 5 * 1000,
        });
      } else if (error.response.config.url == "/api/product/add" || error.response.config.url == "/api/devices/add") {
        console.log("=====");
      } else {
        Message({
          message: error.message,
          type: "error",
          duration: 5 * 1000,
        });
      }
    } else {
      Message({
        message: error.message,
        type: "error",
        duration: 5 * 1000,
      });
    }
    isCloseLoading()
    return Promise.reject(error);
  },
);

export default service;

3.在app.js里添加来控制全局loading显示与隐藏

<template>
  <div id="app" v-loading="isShowLoading">
    <router-view />
  </div>
</template>

<script>
import { mapGetters } from "vuex";
import fakeClickOutSide from "./request/fackClickOutSide.js";
export default {
  name: "App",
  mixins: [fakeClickOutSide],
  computed: {
    ...mapGetters(["isShowLoading"]),
  },
};
</script>

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值