我们平时一个页面可能存在多次loading加载,会在用户端重复刷新,造成很不好的用户体验

造成这个问题的原因是我们通过vuex定义一个loadingShow为true或者false来显示隐藏loading组    件,导致我们在面对多个接口时,会来回操作loadingShow

因为每次请求都会走全局封装的http,所以我们可以在vuex中定义一个{ loadingCount : 0 },每次    请求让loadingCount++,请求结束让 loadingCount--

  

export default {
    state:{
        loadingCount:1,
    },
    getters:{
        getLodingShow:state=>{
            return state.loadingCount?false:true
        }
    },
    mutations:{
        SET_COUNT(state,flag){
            if (flag) {
                state.loadingCount++
            }else{
                state.loadingCount = Math.max(state.loadingCount-1, 0)
                //这里我们用Math.max去取最大值,避免loadingCount出现小于1的情况
            }
        },
    },
    actions:{},
}

 这里我们在vuex中的getters中定义一个 getLoadingShow来控制loading组件的显示隐藏,getters     作为vuex中的计算属性,返回值会根据它的依赖被缓存起来,且只有当它的依赖值发生了改变       才会被重新计算  

 

上面的方法完美的解决了多次loading渲染的问题,我们还可以用class类再次进行一次封装

首先我们定义一个  loading.js

我们现在vuex中定义好控制loading组件的 getLoadingShow

export default {
    state:{
        loadingShow:false
    },
    getters:{
        getLoadingShow:state=>state.loadingShow
    },
    mutations:{
        SET_LOADING(state,flag){
                state.loadingShow=flag
        },
    },
    actions:{},
}

 loading.js 代码

import store from "../store/index";
class LoadingManager {
    count = 0
    isOpen=false
    open(){
        //避免重复改变vuex中的值
        if (!this.isOpen && !store.getters.getLodingShow) {
            store.commit("SET_LOADING",true)
        }
        this.isOpen=true
    }
    close(){
        if(this.isOpen){
            store.commit("SET_LOADING",false)
        }
        this.isOpen=false
    }
    //每次请求count++
    increase(){
        this.count++
        this.refresh()
    }
    //请求结束或者请求失败count--
    decrease(){
        this.count = Math.max(this.count-1, 0)
        //Promise为微任务所以为了避免链式调用的时候loading闪烁问题
        Promise.resolve().then(()=>{
            this.refresh()
        })
        
    }
    refresh(){
        if (this.count>0) {
            //同时也避免多次调用this.open方法
            !this.isOpen && this.open()
        }else{
            this.close()
        }
    }
}
export default new LoadingManager()

  我们将这个方法导入到全局的http.js 进行调用

  

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐