设置全局loading

为什么要设置全局loading?

在项目开发过程中,请求接口的时候延迟没有数据,页面感觉狠卡顿,这个时候就要用loading来做一个延迟界面。

但是每个界面都写loading的话就会很复杂,所以今天给大家带来了一个全局loading的文章,比较适合新手,要具备vuex的基础知识和vue中setup的使用,如果之前没有涉及的话,这边建议去看官网,网上的资料鱼龙混杂。vue的官网写的很好。

每个人都有每个人的全局loading写法。

实现效果

QQ录屏20230613102417

实现思路

loading界面书写:

loading.vue


 loading.css

* {
  margin: 0;
  box-sizing: border-box;
}
.flex-content {
  height: 100%;
  width: 100%;
  display: flex;
  justify-content: center;
  align-items: center;
}

.flex-center:hover {
  transition: transform 0.2s ease;
  border: 1px solid #eee;
  transform: scale(1.1);
  cursor: pointer;
}
.loading{
  display: flex;
  justify-content: center;
  align-items: center;
}
.outer-box {
  width: 3em;
  height: 3em;
  animation: cube-box-ani 1s infinite ease-in-out;
  outline: 1px solid transparent;
}

.large-box {
  height: 3em;
  width: 3em;
  background-color: RGB(42,194,209);
  outline: 1px solid transparent;
}

.small-box {
  height: 3em;
  width: 3em;
  background-color: white;
  z-index: 1;
  outline: 1px solid transparent;
  animation: small-box-ani 1s alternate infinite ease-in-out;
}

@keyframes small-box-ani {
  0% {
    transform: scale(0.2);
  }
  100% {
    transform: scale(0.75);
  }
}

@keyframes cube-box-ani {
  0% {
    transform: rotate(0deg);
  }
  100% {
    transform: rotate(90deg);
  }
}
.text{
  color: RGB(130,130,130);
  margin-top: 20px;
}

store设置loading:

loading.js

export default{
    state: {
        loading: false
    },
    getters: {
    },
    mutations: {
        setLoading(state,flag){
            state.loading = flag
        }
    },
    actions: {
    },
    modules: {
    }
}

store/index.js (这里配置了让vuex数据持久化vuex-persistedstate)

import { createStore } from 'vuex'
import createPersistedState from 'vuex-persistedstate'
import loading from './modules/loading'

const store = createStore({
  state: {
  },
  getters: {
  },
  mutations: {
  },
  actions: {
  },
  modules: {
    loading,
  },
  /* vuex数据持久化配置 */
  plugins: [
    createPersistedState({
      // 存储方式:localStorage、sessionStorage、cookies
      storage: window.sessionStorage,
      // 存储的 key 的key值
      key: "store",
      reducer(state) { //render错误修改
        // 要存储的数据:本项目采用es6扩展运算符的方式存储了state中所有的数据
        return { ...state };
      }
    })
  ]
})
export default store;

设置全局loading.js

loading.js

// 全局loading设置
import store from "@/store";
let loadingNum = 0;

// 开始显示Loading
const startLoading = () => {
  loadingNum++;
  store.commit("setLoading", true);
};
// 关闭Loading
const endLoading = () => {
  loadingNum--;
  if (loadingNum >= 0) {
    store.commit("setLoading", false);
  }
  loadingNum = loadingNum < 0 ? 0 : loadingNum;
};
// 重置函数
const resetLoading = () => {
  loadingNum = 0;
  store.commit("setLoading", false);
};
// 导出
export { startLoading, endLoading, resetLoading };

拦截器配置

请求拦截器 request.js

import axios from "axios";
import { startLoading, endLoading } from "@/assets/js/utils/loading";

//1.利用axios对象的方法create,去创建一个axios实例。
const requests = axios.create({
  //配置对象
  //接口当中:路径都带有/api     基础路径,发送请求的时候,路径当中会出现api
  baseURL: "http://127.0.0.1:8080/",
  //代表请求超时的时间
  timeout: 5000,
});

//请求拦截器:
requests.interceptors.request.use((config) => {
  //解析和上传到后端的时候进行loading加载显示
  startLoading();
  return config;
}),
  (error) => {
    //关闭loading
    endLoading();
    return Promise.reject(error);
  };

//响应拦截器
requests.interceptors.response.use(
  (res) => {
    loading.startLoading();
    return res;
  },
  (error) => {
    loading.endLoading();
    return;
  }
);

//对外暴露
export default requests;

路由拦截器

import { createRouter, createWebHistory } from "vue-router";
import { resetLoading } from "@/assets/js/utils/loading";

const routes = [
  {
    path: '/',
    name: 'main',
    component: () => import("../views/Main.vue")
  },
  {
    path: "/test",
    name: "test",
    component: () => import("../views/Test.vue"),
  },
];

const router = createRouter({
  history: createWebHistory(process.env.BASE_URL),
  routes,
});

router.beforeEach((to, from, next) => {
  // 重置 全局loading
  resetLoading();
  next();
});

export default router;

全局loading要设置在App.vue界面。这样才能做到设置全局loading。

App.vue




这里是不能用v-if判断的,如果在noMounted中使用请求的话,v-if会重新渲染页面,而mounted 又是在重新渲染完成之后调用的。

优化点

有时候,我们有些请求不需要使用loading,下面是动态展示loading

请求格式:

/**
 * 登录 验证邮箱
 * @param {email} data
 * @returns
 */
export const checkEmail = (data) => {
  return request({
    url: "/auth/check-email/" + data,
    method: "get",
    showLoading: false,
  });
};

request.js

//请求拦截器:
requests.interceptors.request.use((config) => {
  if (config.showLoading === undefined) {
    //解析和上传到后端的时候进行loading加载显示
    config.showLoading = true;
    startLoading();
  }
  return config;
}),
  (error) => {
    return Promise.reject(error);
  };

//响应拦截器
requests.interceptors.response.use(
  (res) => {
    if (res.config.showLoading) {
      endLoading();
    }
    return res;
  },
  (error) => {
    return;
  }
);

你可能感兴趣的:(vue.js,前端,javascript)