SockSTap S O C K S T A P

Vue3项目中的骨架屏

首页 / 新闻资讯 / 正文

实现场景:刚进入页面的时候,需要后端接口回传的数据,还没有回来,为了客户有更好的体验,需要设置骨架屏,效果图如下:

 实现步骤:

1.设置通用组件骨架屏(可以设置的属性:高,宽,背景颜色,是否有闪动画)

基本传值如下图:

2.设置业务组件骨架屏

1).设置通用组件骨架屏基本构建

 src/components/library/Skeleton.vue

<template> <div class="skeleton" :style="{width,height}" :class="{shan:animated}"> <!-- 1 盒子--> <div class="block" :style="{backgroundColor:bg}"></div>  //一个盒子包含了另一个盒子,样式写在                                                                                                                              // 一个div中也是可以的 <!-- 2 闪效果 xtx-skeleton 伪元素 ---> </div> </template> <script> export default { name: 'Skeleton', // 使用的时候需要动态设置 高度,宽度,背景颜色,是否闪下 props: { bg: { type: String, default: '#efefef' }, width: { type: String, default: '100px' }, height: { type: String, default: '100px' }, animated: { type: Boolean, default: false } } } </script> <style scoped lang="less"> .skeleton { display: inline-block; position: relative; overflow: hidden; vertical-align: middle; .block { width: 100%; height: 100%; border-radius: 2px; } } .shan { &::after { content: ""; position: absolute; animation: shan 1.5s ease 0s infinite; top: 0; width: 50%; height: 100%; background: linear-gradient( to left, rgba(255, 255, 255, 0) 0, rgba(255, 255, 255, 0.3) 50%, rgba(255, 255, 255, 0) 100% ); transform: skewX(-45deg); } } @keyframes shan { 0% { left: -100%; } 100% { left: 120%; } } </style>

 全局注册(main.js中记得导入这个文件,并用Vue中use注册)

src/componets/library/index.j

import Skeleton from './Skeleton.vue'  export default { install (app) {  app.component(Skeleton.name, XtxSkeleton) } }

实现第一个图

 src/views/home/components/home-cate.vue

<ul class="menu"> <li :class="{active:categoryId===item.id}" v-for="item in list" :key="item.id" @mouseenter="categoryId=item.id"> <RouterLink to="/">{{item.name}}</RouterLink> <template v-if="item.children"> <RouterLink to="/" v-for="sub in item.children" :key="sub.id">{{sub.name}}</RouterLink> </template>  <span v-else>  <Skeleton width="60px" height="18px" style="margin-right:5px" bg="rgba(255,255,255,0.2)" />  <Skeleton width="50px" height="18px" bg="rgba(255,255,255,0.2)" />  </span> </li> </ul>

封装业务组件src/views/home/components/home-skeleton.vue,实现第二图的效果

<template> <div class='home-skeleton'> <div class="item" v-for="i in 4" :key="i" :style="{backgroundColor:bg}"> <Skeleton bg="#e4e4e4" width="306px" height="306px" animated /> <Skeleton bg="#e4e4e4" width="160px" height="24px" animated /> <Skeleton bg="#e4e4e4" width="120px" height="24px" animated /> </div> </div> </template>  <script> export default { name: 'HomeSkeleton', props: { bg: { type: String, default: '#fff' } } } </script>  <style scoped lang='less'> .home-skeleton { width: 1240px; height: 406px; display: flex; justify-content: space-between; .item { width: 306px; .xtx-skeleton ~ .xtx-skeleton{ display: block; margin: 16px auto 0; } } } </style>

在需要用的组件中,导入业务组件使用

<HomePanel title="人气推荐" sub-title="人气爆款 不容错过">  <Transition name="fade">  // 配合了vue中的淡入淡出的动画  <ul v-if="goods.length" ref="pannel" class="goods-list">  // v-if有数据显示数据 <li v-for="item in goods" :key="item.id"> <RouterLink to="/"> <img :src="item.picture" alt=""> <p class="name">{{item.title}}</p> <p class="desc">{{item.alt}}</p> </RouterLink> </li> </ul>  <HomeSkeleton v-else />   // 没有数据就显示骨架  </Transition>  </div> </HomePanel>