Vue页面跳转优化,loading中间状态和骨架屏

Vue页面跳转优化,loading中间状态和骨架屏

milugloomy 

用vuex的dispatch提交变量好像不行

原因

先看一段简单、常规的vue代码。

<template>
    <div v-if="list && list.length>0">
    <div v-for="row in list">
    <span>{{row.xxx}}</span>
    //显示剩下数据
    </div>
    </div>
    <div v-else>
    <div>暂无数据</div>
    </div>
</template>
<script>
export default {
    created() {
        this.ajaxform('/chronic/xxx').then(res => {
            this.list = res.body
        })
    }
}
</script>

这段代码在created生命周期函数内会调用后端接口获取数据,我们假设获取数据的时间需要1秒。那么打开页面后将显示“暂无数据”,1秒后才会显示列表数据,给客户的体验有些不好。这篇文章就来解决这个打开页面先显示暂无数据的问题。

思路

我们希望能加入一个过渡状态,在ajax请求加载数据时显示“数据加载中”,数据加载完成后再根据有无数据来显示列表或是“暂无数据”。当跳转页面时,流程如下图:

但不能所有的ajax请求都显示数据加载中,只能是打开页面后立即执行的ajax请求显示加载中,也就是created、mounted中执行的ajax请求显示加载中。

方案

首先我们需要一个全局变量来储存当前正在执行的ajax请求的数量以及是否是页面刚打开的状态。我将这两个变量存在了store中

 
  1. const state = {

  2. pageInit: false,

  3. // 记录有几个ajax请求正在执行中

  4. ajaxCount: 0,

  5. }

  6. const mutations = {

  7. updatePageInit: function (state, pageInit) {

  8. state.pageInit = pageInit

  9. },

  10. updateAjaxCount: function (state, count) {

  11. state.ajaxCount = state.ajaxCount + count

  12. }

  13. }

  14. export default {

  15. namespaced: true,

  16. state,

  17. mutations

  18. }

然后因为项目中发起ajax请求的组建使用的是axios,所以可以在axios的request、response拦截器中,对这个数进行加减。请求开始,则对ajaxCount加1,请求成功或是失败对ajaxCount减1

 
  1. axios.interceptors.request.use(

  2. config => {

  3. store.commit('user/updateAjaxCount', 1)

  4. return config

  5. },

  6. error => {

  7. store.commit('user/updateAjaxCount', -1)

  8. return Promise.reject(error)

  9. }

  10. )

  11. axios.interceptors.response.use(

  12. response => {

  13. store.commit('user/updateAjaxCount', -1)

  14. return response

  15. },

  16. error => {

  17. store.commit('user/updateAjaxCount', -1)

  18. return Promise.reject(error)

  19. }

  20. )

在router的afterEach函数中对pageInit的值进行更新,也就是设置为刚打开页面的状态

 
  1. router.afterEach(function (to, from) {

  2. store.commit('user/updatePageInit', true)

  3. })

再然后在App.vue中要做两件事情

1、在template中,通过私有变量loading的值显示、隐藏<router-view>和加载状态(菊花动图)。

2、对ajaxCount进行watch,当ajaxCount大于0,且是刚进入页面的状态时,设置私有变量loading为true,显示加载中状态。

     当ajaxCount等于0时,也就是ajax请求全部结束时,设置私有变量loading为false,关闭加载中状态,设置pageInit为false,显示数据。

<template>
    <div style='height:100%;'>
        <router-view v-show="!loading"></router-view>
        <div v-show="loading"><img src="xxx/juhua.gif"></div><!-- 转菊花的动图 -->
    </div>
</template>

<script>

export default {

name: 'app',

data () {

return {

loading: false

}

},

computed: mapState({

pageInit: state => state.user.pageInit,

ajaxCount: state => state.user.ajaxCount

}),

watch: {

ajaxCount (count) {

// count>0表示有ajax请求正在执行中, pageInit表示刚进入新页面, loading表示菊花转的状态

if (count > 0 && this.pageInit && this.loading === false) {

this.loading = true

}

if (count === 0) {

this.loading = false

this.$store.commit('user/updatePageInit', false)

}

}

}

}

</script>

以下是效果图,第一张加载中状态是转菊花的图,第二张加载中状态是骨架屏的图

       

结语

我们加载中状态显示的很简单,只是转菊花,这里也可以做的效果更好一些,例如骨架屏等。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值