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