skeleton.vue代码
<template>
<view>
<view class="skeleton" v-show="loading" :class="[animationClass]" v-for="skeleton in count">
<view class="row" :style="{'flex-direction':direction}" >
<view v-for="(item,index) in row" :key="item" class="row-item" :style="{'margin-right':mright}" >
<view :style="{width:rowWidth,height:rowHeight,'border-radius':radius}" v-if="variant === 'image'" :class="[varianttype]">
<svg viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg">
<path d="M64 896V128h896v768H64z m64-128l192-192 116.352 116.352L640 448l256 307.2V192H128v576z m224-480a96 96 0 1 1-0.064 192.064A96 96 0 0 1 352 288z"/>
</svg>
</view>
<view v-else :class="[varianttype]" :style="{width:rowWidth,height:rowHeight}" class="row-class"></view>
</view>
</view>
</view>
<slot v-if="!loading"></slot>
</view>
</template>
<script>
export default {
props: {
//是否使用动画
animate: {
type: Boolean,
default: false
},
//渲染多少个 template, 建议使用尽可能小的数字
count: {
type: Number,
default: 1
},
//是否显示 skeleton 骨架屏
loading: {
type: Boolean,
default: true
},
//骨架屏段落数量
row: {
type: Number,
default: 1
},
//段落行宽度,默认为100%
rowWidth:{
type: String | Number,
default: '100%'
},
//段落行高度
rowHeight:{
type: String | Number,
},
//圆角的边框
radius:{
type: String | Number
},
//调整主轴方向
direction:{
type: String,
default: 'column'
},
//右侧外边距
mright:{
type: String | Number
},
//当前显示的占位元素的样式
variant: {
type: String,
values: [
'circle',
'h1',
'h3',
'text',
'caption',
'p',
'image',
'button',
],
default: 'text'
}
},
computed: {
animationClass() {
return [this.animate ? 'skeleton_animation' : '']
},
varianttype(){
return [this.variant ? 'skeleton__'+this.variant : 'text']
}
},
data() {
return {
}
}
}
</script>
<style lang="scss" scoped>
/* 占位元素的样式 */
$skeleton-h1-height: 20px;
$skeleton-h3-height: 18px;
$skeleton-caption-height: 12px;
$skeleton-button-height:40px;
$skeleton-button-width:64px;
$skeleton-circle-width:36px;
$skeleton-circle-height:36px;
$skeleton-text-height:13px;
$skeleton-p-height:13px;
$skeleton-image-width:200px;
$skeleton-image-height:200px;
$skeleton-image-svg-width:22%;
$skeleton-image-svg-height:22%;
.skeleton {
background-color: #fff;
}
.row{
display: flex;
}
.row-class {
width: 100%;
height: 16px;
margin-top: 12px;
display: flex;
}
.row-item{
width: 100%;
}
.row-item:nth-last-child(1){
margin-right: 0 !important;
}
.skeleton_animation .row-class,.skeleton__image {
background: linear-gradient(
90deg,#f2f2f2 25%,#e6e6e6 37%,#f2f2f2 63%);
background-size: 400% 100%;
animation: skeleton-loading 1.4s ease infinite;
}
@keyframes skeleton-loading{
0%{
background-position:100% 50%
}
to{
background-position:0 50%
}
}
.skeleton__h1 {
height: $skeleton-h1-height;
}
.skeleton__h3 {
height: $skeleton-h3-height;
}
.skeleton__caption {
height: $skeleton-caption-height;
}
.skeleton__button {
height: $skeleton-button-height;
width: $skeleton-button-width;
border-radius: 4px;
}
.skeleton__circle {
height: $skeleton-circle-height;
width: $skeleton-circle-width;
border-radius: 50%;
line-height: $skeleton-circle-height;
}
.skeleton__text {
width: 100%;
height: $skeleton-text-height;
}
.skeleton__p {
flex-shrink: 0;
width: 100%;
height: $skeleton-p-height;
}
.skeleton__image {
margin-right: 8px;
width: $skeleton-image-width;
height:$skeleton-image-height;
background-color: #f2f2f2;
display: flex;
align-items: center;
justify-content: center;
border-radius: 0;
}
.row-item:nth-last-child(1) .skeleton__image{
margin-right: 0px;
}
.skeleton__image svg {
fill: #dcdde0;
width: $skeleton-image-svg-width;
height: $skeleton-image-svg-height;
}
</style>
## skeleton 骨架屏 示例代码
# skeleton 骨架屏
在需要等待加载内容的位置设置一个骨架屏,用法同 [elementui Skeleton 骨架屏](https://element.eleme.io/#/zh-CN/component/skeleton)类似。
## 属性说明
|属性名|类型|默认值|说明|
| -- | -- | --|--|
| animate | Boolean | false | 是否使用动画 |
| count | Number | 1 | 渲染多少个 template, 建议使用尽可能小的数字 |
| loading | Boolean | false | 是否显示 skeleton 骨架屏 |
| row | Number | 1 | 骨架屏段落数量 |
| rowWidth | String/Number | 100% | 段落行宽度,默认为100% |
| rowHeight | String/Number | | 段落行高度,无默认值 |
| radius | String/Number | | 圆角的边框,无默认值 |
| direction | String |column | 调整主轴方向,默认值为 column |
| mright | String/Number | | 右侧外边距,无默认值 |
| variant | String |text| 当前显示的占位元素的样式,可选值 p / text / h1 / h3 / caption / button / image / circle |
## 示例代码
```html
<template>
<view>
<view class="content">
<skeleton :row="4" direction='row' rowWidth="80px" radius='50%' rowHeight="80px" :animate='true' :loading='loading' variant='image'>
<view class="imagelist-1">
<image src='https://images.unsplash.com/photo-1543466835-00a7907e9de1?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1548&q=80'></image>
<image src='https://images.unsplash.com/photo-1543466835-00a7907e9de1?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1548&q=80'></image>
<image src='https://images.unsplash.com/photo-1543466835-00a7907e9de1?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1548&q=80'></image>
<image src='https://images.unsplash.com/photo-1543466835-00a7907e9de1?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1548&q=80'></image>
</view>
</skeleton>
<br/>
<skeleton :row="4" direction='row' rowWidth="80px" rowHeight="80px" :animate='true' :loading='loading' variant='image'>
<view class="imagelist-2">
<image src='https://images.unsplash.com/photo-1543466835-00a7907e9de1?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1548&q=80'></image>
<image src='https://images.unsplash.com/photo-1543466835-00a7907e9de1?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1548&q=80'></image>
<image src='https://images.unsplash.com/photo-1543466835-00a7907e9de1?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1548&q=80'></image>
<image src='https://images.unsplash.com/photo-1543466835-00a7907e9de1?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1548&q=80'></image>
</view>
</skeleton>
<br/>
<skeleton :row='3' direction='column' rowWidth="100%" rowHeight="13px" :animate='true' :loading='loading' variant='p'>
<view >
<p>测试新闻标题1号</p>
<p>测试新闻标题2号</p>
<p>测试新闻标题3号</p>
</view>
</skeleton>
<br/>
<skeleton rowWidth="80px" direction='row' radius='50%' rowHeight="80px" :animate='true' :loading='loading' variant='image'>
<view >
<image src='https://images.unsplash.com/photo-1543852786-1cf6624b9987?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=774&q=80'></image>
</view>
</skeleton>
<skeleton :animate='true' :loading='loading' variant='h1'>
<view >
<h1>标题</h1>
</view>
</skeleton>
<skeleton :row='2' mright='8px' direction='row' :animate='true' :loading='loading' variant='text'>
<view >
<text>描述</text>
</view>
</skeleton>
<skeleton :row='3' mright='8px' direction='row' :animate='true' :loading='loading' variant='text'>
<view >
<text>描述</text>
</view>
</skeleton>
<skeleton :row='4' mright='8px' direction='row' :animate='true' :loading='loading' variant='text'>
<view >
<text>描述</text>
</view>
</skeleton>
</view>
</view>
</template>
<script>
import skeleton from '../../components/lidao-skeleton/skeleton.vue'
export default {
data() {
return {
loading: true // 是否显示骨架屏组件
}
},
onLoad() {
// 通过延时模拟向后端请求数据,调隐藏骨架屏
setTimeout(() => {
this.loading = false;
}, 3000)
},components:{
skeleton,
}
}
</script>
<style>
page{
padding: 12px;
}
image{
width: 80px;
height: 80px;
margin-right: 8px;
}
.imagelist-1 image{
border-radius: 50%;
}
.imagelist-1 image:nth-last-child(1){
margin-right: 0;
}
.imagelist-2 image:nth-last-child(1){
margin-right: 0;
}
</style>
```
## 效果图
