路由跳转页面丝滑过渡,减少白屏时间——loading?骨架屏

今日心情一般,效率不高撒

关于路由函数的使用可以去下文看哦!!非常全

一.先说结论,用loading还是骨架屏?

测试了一下loading和骨架屏在时耗上并没有多少区别,具体的使用还是要结合用户体验考虑,

在从A页面切换到B页面时,用户未访问过B页面,使用骨架屏可以给用户预先了解页面框架,提升用户体验

在从A页面切换到A页面时,但是携带了不同数据,存在一个数据刷新的问题,我考虑的是为避免网络差,请求时间过长,骨架屏带给用户的一种宕机的感觉,因为这个时候用户已经见过框架了,所以直接用loading就可以

当然具体用什么,听产品的!!!

二.在什么时候请求获得新数据呢,开或关骨架屏和loading?

1.尽可能早的接受传参并更块的触发请求函数能够更快得到数据

Vue 路由导航守卫(全局守卫、路由独享守卫、组件内守卫)详解_离开页面时移除全局前置守卫(beforeeach守卫-优快云博客

beforeRouteEnter函数是在setup前!(要写在setup函数外边

beforeRouteUpdate函数指组件是非首次进入触发,不会再触发created和mounted

在这两个函数中触发请求函数

2.页面的跳转有两种情况:

①.从A页面跳转到test页面下,页面经过:

离开A页面 --》(beforeRouteEnter )骨架屏 --》数据请求完成并重新渲染

②.从test页面test页面,只是更新了参数信息,页面经过:

test页面老数据 --》(beforeRouteUpdate)loadiing --》test页面新数据

三.在函数中的处理:开骨架屏(开loading)--》请求数据--》关骨架屏(关loading)

代码如下,用延时函数来模仿请求数据,说几个注意点

①.骨架屏的使用,在初始无数据的时候,可以先估计可视页面有多少个item项来准备骨架屏,如果你要在非首次进入页面时使用骨架屏,为了不根据旧数据生成骨架屏,要先对数据进行初始化处理,具体看我备注那段要看更新数据骨架屏效果,函数换为备注那段即可,html需要稍加修改

②.注意骨架屏或loading的开关,在请求数据到得到数据的前后

③.代码不用看太细,因为是前台数据,所以加了些处理,向后台请求数据的时候没有这么乱

<script>
import { ref, onMounted } from 'vue'
import { onBeforeRouteUpdate } from 'vue-router'
import { useRouter } from 'vue-router'

const LIST_INFO = [
  {
    name: 'QQ',
    describe: 'QQ是腾讯公司推出的一款即时通讯软件',
  },
  {
    name: '微信',
    describe: '微信是腾讯公司推出的一款即时通讯软件',
  },
  {
    name: '钉钉',
    describe: '钉钉是阿里巴巴推出的一款即时通讯软件',
  },
  {
    name: '飞书',
    describe: '飞书是字节跳动推出的一款即时通讯软件',
  },
  {
    name: '企业微信',
    describe: '企业微信是腾讯公司推出的一款即时通讯软件',
  },
  {
    name: 'TIM',
    describe: 'TIM是腾讯公司推出的一款即时通讯软件',
  },
  {
    name: 'QQ邮箱',
    describe: 'QQ邮箱是腾讯公司推出的一款邮箱软件',
  },
]
const LIST_INFO1 = [
  {
    name: 'QQ',
    describe: 'QQ是腾讯公司推出的一款即时通讯软件',
  },
  {
    name: '微信',
    describe: '微信是腾讯公司推出的一款即时通讯软件',
  },
  {
    name: '钉钉',
    describe: '钉钉是阿里巴巴推出的一款即时通讯软件',
  },
  {
    name: '飞书',
    describe: '飞书是字节跳动推出的一款即时通讯软件',
  },
  {
    name: '企业微信',
    describe: '企业微信是腾讯公司推出的一款即时通讯软件',
  },
  {
    name: 'TIM',
    describe: 'TIM是腾讯公司推出的一款即时通讯软件',
  },
  {
    name: 'QQ邮箱',
    describe: 'QQ邮箱是腾讯公司推出的一款邮箱软件',
  },
  {
    name: '网易邮箱',
    describe: '网易邮箱是网易公司推出的一款邮箱软件',
  },
  {
    name: '新浪邮箱',
    describe: '新浪邮箱是新浪公司推出的一款邮箱软件',
  },
  {
    name: '搜狐邮箱',
    describe: '搜狐邮箱是搜狐公司推出的一款邮箱软件',
  },
  {
    name: '139邮箱',
    describe: '139邮箱是中国移动推出的一款邮箱软件',
  },
  {
    name: '163邮箱',
    describe: '163邮箱是网易公司推出的一款邮箱软件',
  },
  {
    name: '126邮箱',
    describe: '126邮箱是网易公司推出的一款邮箱软件',
  },
  {
    name: 'QQ音乐',
    describe: 'QQ音乐是腾讯公司推出的一款音乐软件',
  },
  {
    name: '网易云音乐',
    describe: '网易云音乐是网易公司推出的一款音乐软件',
  },
  {
    name: '酷狗音乐',
    describe: '酷狗音乐是酷狗公司推出的一款音乐软件',
  },
]
export default {
  beforeRouteEnter(to, from, next) {
    console.log('首次进入组件')
    next((vm) => {
      vm.skeletonLoading = true // 更新 skeletonLoading 状态
      setTimeout(() => {
        // 在url有参数的情况下优先展示参数对应的数据
        vm.data = to.query.list_Info ? JSON.parse(to.query.list_Info) : LIST_INFO
        // console.log('data.value', vm.data)
        vm.skeletonLoading = false // 更新 skeletonLoading 状态
      }, 2000)
    })
  },
  created() {
    console.log('created')
  },
  setup() {
    const data = ref(20)
    const skeletonLoading = ref(true) // 初始化为 true
    const loading = ref(false) // 初始化为 true
    const router = useRouter()
    onBeforeRouteUpdate((to) => {
      console.log('再次进入组件')
      loading.value = true // 更新 loading 状态
      setTimeout(() => {
        try {
          data.value = JSON.parse(to.query.list_Info)
          // console.log('data.value', data.value)
          loading.value = false // 更新 loading 状态
        } catch {
          //当二次进入页面后,也就是url会有query参数,这个时候点击回退,url会变成首次进入的状态就是没有query参数,因为这次回退本质上是再次进入组件,执行onBeforeRouteUpdate函数,to.query.list_Info数据没有一次会报错,导致loading状态一直为true,所以要抛出异常,更改data和loading,如果是正常情况的话首次进入这个页面,也是会有参数的
          setTimeout(() => {
            data.value = LIST_INFO
            loading.value = false // 更新 loading 状态
          }, 2000)
        }
      }, 2000)
    })
    // onBeforeRouteUpdate((to) => {
    //   console.log('再次进入组件')
    //   data.value = 20
    //   skeletonLoading.value = true // 更新 loading 状态
    //   setTimeout(() => {
    //     try {
    //       data.value = JSON.parse(to.query.list_Info)
    //       console.log('data.value', data.value)
    //       skeletonLoading.value = false // 更新 loading 状态
    //     } catch {
    //       //当二次进入页面后,也就是url会有query参数,这个时候点击回退,url会变成首次进入的状态就是没有query参数,因为这次回退本质上是再次进入组件,执行onBeforeRouteUpdate函数,to.query.list_Info数据没有一次会报错,导致loading状态一直为true,所以要抛出异常,更改data和loading,如果是正常情况的话首次进入这个页面,也是会有参数的
    //       setTimeout(() => {
    //         data.value = LIST_INFO
    //         skeletonLoading.value = false // 更新 loading 状态
    //       }, 2000)
    //     }
    //   }, 2000)
    // })
    const handleGetMoreInfo = () => {
      console.log(LIST_INFO1)
      router.push({
        path: '/test',
        query: { list_Info: JSON.stringify(LIST_INFO1) },
      })
    }
    onMounted(() => {
      console.log('mounted')
    })
    return { data, loading, skeletonLoading, handleGetMoreInfo }
  },
}
</script>
<template>
  <div class="app-store-container">
    <h1>应用商店大全</h1>
    <div class="btn">
      <a-button type="primary" @click="handleGetMoreInfo">点击获得更多应用信息</a-button>
    </div>
    <div class="loading" v-if="loading"><a-spin />加载中...</div>
    <div v-else class="app-store-list">
      <div class="app-store-item" v-for="(item, index) in data" :key="index">
        <a-skeleton :loading="skeletonLoading" active :paragraph="{ rows: 2 }">
          <div class="app-store-name">{{ item.name }}</div>
          <div class="app-store-describe">{{ item.describe }}</div>
        </a-skeleton>
      </div>
    </div>
  </div>
</template>
<style lang="less" scoped>
.app-store-container {
  width: 100%;
  min-height: 100vh;
  background-color: rgb(244, 250, 194);
  h1 {
    text-align: center;
    padding: 20px 0;
  }
  .btn {
    text-align: end;
    margin: 30px 20px;
  }
  .loading {
    height: calc(100vh - 200px);
    display: flex;
    justify-content: center;
    align-items: center;
    font-size: 30px;
  }
  .app-store-list {
    display: grid;
    font-size: 18px;
    grid-template-columns: 1fr 1fr 1fr 1fr 1fr;
    flex-wrap: wrap;
    .app-store-item {
      min-width: 180px;
      padding: 25px 10px 30px;
      margin: 10px;
      border: solid 1px #ccc;
      background-color: rgb(245, 236, 157);
      .app-store-name {
        padding-bottom: 10px;
      }
      .app-store-describe {
        line-height: 35px;
      }
    }
  }
  @media screen and (max-width: 1000px) and (min-width: 800px) {
    .app-store-list {
      grid-template-columns: 1fr 1fr 1fr 1fr;
    }
  }
  @media screen and (max-width: 800px) and (min-width: 600px) {
    .app-store-list {
      grid-template-columns: 1fr 1fr 1fr;
    }
  }
  @media screen and (max-width: 600px) and (min-width: 400px) {
    .app-store-list {
      grid-template-columns: 1fr 1fr;
    }
  }
}
</style>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值