封装axios加载动画Loding——vuex+axios拦截器

前言:我们在axios发送请求时候,会存在请求等待时长,我们一般会加一个动画,如果很多个时候一个一个的加动画代码看起来很臃肿很冗余,我们写起来也很麻烦,所以为了更好的写代码,把动画封装在axios中请求前打开动画,请求后关闭动画就实现了Loding加载的效果
下面通过样例演示如何封装一个带 loading 效果的 Axios 组件,它能够对请求和响应进行拦截从而实现 loading 的自动显示与隐藏,

两种方法搭配
(1) vue+element
(2) vue+vuex+自己封装的动画组件
此文章讲第二种方法

一、创建一个vue组件名字为Loading(动画组件,按照自己喜好来)

<template>
    <div ref="loader" class="loaderfather" v-show="isShowLoader">
        <div class="loader">Loading...</div>
    </div>
</template>
<script>
    export default {
        name: "Loader",
        data() {
            return {};
        },
        props: {
            isShowLoader: {
                type: Boolean,
                default () {
                    false;
                },
            },
        },
        methods: {},
    };
</script>

<style>
    .loaderfather {
        position: fixed;
        top: 0;
        right: 0;
        bottom: 0;
        left: 0;
        background-color: rgba(0, 0, 0, 0.5);
        display: flex;
        justify-content: center;
        align-items: center;
        z-index: 20000;
    }

    .loader {
        margin: auto;
        font-size: 20px;
        width: 0.5em;
        height: 0.5em;
        border-radius: 50%;
        text-indent: 9999em;
        animation: load-effect 1s infinite linear;
    }

    @keyframes load-effect {
        0% {
            box-shadow:
                /* 0:左移3em -3em:下移2em 0:模糊距离0,即纯色 .2em:外扩.2em  #504f4e:白色 */

                0 -3em 0 0.2em #504f4e,
                /*上*/
                2em -2em 0 0 #504f4e,
                /*右上*/
                3em 0 0 -0.5em #504f4e,
                /*右*/
                2em 2em 0 -0.5em #504f4e,
                /*右下*/
                0 3em 0 -0.5em #504f4e,
                /*下*/
                -2em 2em 0 -0.5em #504f4e,
                /*左下*/
                -3em 0 0 -0.5em #504f4e,
                /*左*/
                -2em -2em 0 0 #504f4e;
            /*左上*/
        }

        12.5% {
            box-shadow: 0 -3em 0 0 #504f4e, 2em -2em 0 0.2em #504f4e, 3em 0 0 0 #504f4e,
                2em 2em 0 -0.5em #504f4e, 0 3em 0 -0.5em #504f4e,
                -2em 2em 0 -0.5em #504f4e, -3em 0 0 -0.5em #504f4e,
                -2em -2em 0 -0.5em #504f4e;
        }

        37.5% {
            box-shadow: 0 -3em 0 -0.5em #504f4e, 2em -2em 0 -0.5em #504f4e,
                3em 0 0 0 #504f4e, 2em 2em 0 0.2em #504f4e, 0 3em 0 0 #504f4e,
                -2em 2em 0 -0.5em #504f4e, -3em 0 0 -0.5em #504f4e,
                -2em -2em 0 -0.5em #504f4e;
        }

        50% {
            box-shadow: 0 -3em 0 -0.5em #504f4e, 2em -2em 0 -0.5em #504f4e,
                3em 0 0 -0.5em #504f4e, 2em 2em 0 0 #504f4e, 0 3em 0 0.2em #504f4e,
                -2em 2em 0 0 #504f4e, -3em 0 0 -0.5em #504f4e, -2em -2em 0 -0.5em #504f4e;
        }

        62.5% {
            box-shadow: 0 -3em 0 -0.5em #504f4e, 2em -2em 0 -0.5em #504f4e,
                3em 0 0 -0.5em #504f4e, 2em 2em 0 -0.5em #504f4e, 0 3em 0 0 #504f4e,
                -2em 2em 0 0.2em #504f4e, -3em 0 0 0 #504f4e, -2em -2em 0 -0.5em #504f4e;
        }

        75% {
            box-shadow: 0 -3em 0 -0.5em #504f4e, 2em -2em 0 -0.5em #504f4e,
                3em 0 0 -0.5em #504f4e, 2em 2em 0 -0.5em #504f4e, 0 3em 0 -0.5em #504f4e,
                -2em 2em 0 0 #504f4e, -3em 0 0 0.2em #504f4e, -2em -2em 0 0 #504f4e;
        }

        87.5% {
            box-shadow: 0 -3em 0 0 #504f4e, 2em -2em 0 -0.5em #504f4e,
                3em 0 0 -0.5em #504f4e, 2em 2em 0 -0.5em #504f4e, 0 3em 0 -0.5em #504f4e,
                -2em 2em 0 0 #504f4e, -3em 0 0 0 #504f4e, -2em -2em 0 0.2em #504f4e;
        }

        100% {
            box-shadow: 0 -3em 0 0.2em #504f4e, 2em -2em 0 0 #504f4e,
                3em 0 0 -0.5em #504f4e, 2em 2em 0 -0.5em #504f4e, 0 3em 0 -0.5em #504f4e,
                -2em 2em 0 -0.5em #504f4e, -3em 0 0 -0.5em #504f4e, -2em -2em 0 0 #504f4e;
        }
    }
</style>

二、创建一个store.js文件引入vuex

import {createStore} from 'vuex'

// Create a new store instance.
const store = createStore({
    getters: {},
    state: {
        loadingShow: true,
    },
    mutations: {
        showLoading(state) {
            state.loadingShow = true
        },
        hideLoading(state) {
            state.loadingShow = false
        }
    },
    actions: {},
})
export default store

之前我们经常看到vuex运行是下边代码

import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)

export default new Vuex.Store({
  state: {
    skin: 'HH',
    loadingShow: true,
  },
  mutations: {
    changeSkin (state, str) {
      state.skin = str
    },
    showLoading (state) {
      state.loadingShow = true
    },
    hideLoading (state) {
      state.loadingShow = false
    }
  },
  actions: {

  }
})

为什么我们不这么干,因为我们用的是vue3.0版本,所以我们创建import {createApp} from 'vue’
得到的是一个函数,然后参数为根组件APP时候创建出来的,而我们如果直接**import Vue from
‘vue’,**得到的是undefined
那么vuex此时应该选择哪个版本?
4.0
为什么?
如果选择3.几版本那么我们引用是 import Vuex from ‘vuex’ 但是有一个问题,此时需要Vue.use(vuex),这个时候的Vue已经是一个实例了,但是我们vue3中,是引入的一个构造函数createApp
所以要采用vuex4.0版本,然后直接 import {createStore} from 'vuex’
如果你的vue版本是2那么第二种没毛病,如果vue版本是3则第一种
(当然这也是个人观点,如有建议请留言及时更正)

三、创建一个http.js文件,引入axios然后封装

import axios from 'axios'
import store from '../../store'
// 添加请求拦截器
axios.interceptors.request.use(function (config) {
  // 在发送请求之前做些什么

  // 调用store showLoading方法
  store.commit('showLoading')
  console.log('loading...')
  return config;
}, function (error) {
  // 对请求错误做些什么
  store.commit('hideLoading')
  return Promise.reject(error);
});

// 添加响应拦截器
axios.interceptors.response.use(function (response) {
  // 对响应数据做点什么

  // 调用store hideLoading方法
  store.commit('hideLoading')
  console.log('end...')
  return response;
}, function (error) {
  // 对响应错误做点什么
  store.commit('hideLoading')
  return Promise.reject(error);
});

四、在的main.js中引入vue和根组件

import {createApp} from 'vue'
import App from './App.vue'
import axioshttp from './http'//引用http封装的axios组件
import store from "./store"

var app = createApp(App)
app.use(store)//绑在app上
app.config.globalProperties.$axios = axioshttp ;
app.config.globalProperties.$app = app;
app.mount('#app')

提示:
import {createApp} from 'vue’是vue3.0版本内容
createApp方法可以返回一个提供应用上下文的应用实例,应用实例挂载的整个组件树共享同一个上下文,vue3中的createApp方法进行实例创建,和vue2的区别自己看

import axioshttp from ‘./http’//引用http封装的axios组件
app.config.globalProperties.$axios = axioshttp ;

此时我们把Loading组件引用到根组件下即可

<Loading :isShowLoader="this.$store.state.loadingShow"></Loading>

this.$store.state.loadingShow就是我们vuex定义的全局的状态管理变量
在这里插入图片描述
中间是圆圈打转转,截图有点快,不完整,凑合看吧,可以把动画复制下来看一下!

下一篇文章讲一下简单的element+vue简单的封装———— # take root_80

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐