小程序骨架屏(mpvue)
小程序骨架屏
1, 引入插件
<template>
<div>
<div class="wrap"
:style="{'width':systemInfo.width+'px','height':systemInfo.height+'px', 'background-color':bgcolor}">
<div v-for="(item,index) in skeletonRectLists"
:index='index'
:key='item'
class="chiaroscuro"
:class="loading=='chiaroscuro'? 'chiaroscuro':''"
:style="{'width':item.width+'px','height':item.height+'px','background-color':'rgba(233, 2, 233,1)','position':'absolute','left':item.left+'px','top':item.top+'px'}">
</div>
<div v-for="(item,index) in skeletonCircleLists"
:index='index'
:key='item'
class="chiaroscuro"
:class="loading == 'chiaroscuro' ? 'chiaroscuro' : ''"
:style="{'width':item.width+'px','height':item.height+'px','background-color':'rgba(233, , 233,1)','border-radius':item.width+'px','position':'absolute','left':item.left+'px','top':item.top+'px'}">
</div>
</div>
</div>
</template>
<script>
/* eslint-disable */
export default {
props: {
bgcolor: { type: String, value: '#FFF' },
selector: { type: String, value: 'skeleton' },
loading: { type: String, value: 'spin' },
},
data() {
return {
loadingAni: ['spin', 'chiaroscuro'],
systemInfo: {},
skeletonRectLists: [],
skeletonCircleLists: [],
};
},
components: {},
methods: {
rectHandle: function() {
const that = this;
//绘制不带样式的节点
wx
.createSelectorQuery()
.selectAll(`.${this.selector}-rect`)
.boundingClientRect()
.exec(function(res) {
that.skeletonRectLists = res[0];
});
},
radiusHandle: function() {
const that = this;
wx
.createSelectorQuery()
.selectAll(`.${this.selector}-radius`)
.boundingClientRect()
.exec(function(res) {
that.skeletonCircleLists = res[0];
});
},
},
onLoad: function() {
//默认的首屏宽高,防止内容闪现
const systemInfo = wx.getSystemInfoSync();
(this.systemInfo = {
width: systemInfo.windowWidth,
height: systemInfo.windowHeight,
}),
(this.loading = this.loadingAni.includes(this.loading) ? this.loading : 'spin');
const that = this;
//绘制背景
wx
.createSelectorQuery()
.selectAll(`.${this.selector}`)
.boundingClientRect()
.exec(function(res) {
that.systemInfo.height = res[0][0].height + res[0][0].top || 0;
});
//绘制矩形
this.rectHandle();
//绘制圆形
this.radiusHandle();
},
};
/* eslint-enable */
</script>
<style scoped>
.wrap {
position: absolute;
left: 0;
top: 0;
z-index: 9998;
overflow: hidden;
}
.chiaroscuro {
animation-duration: 1s;
animation-fill-mode: forwards;
animation-iteration-count: infinite;
animation-name: placeHolderShimmer;
animation-timing-function: linear;
background: #f6f7f8;
background: linear-gradient(to right, #eeeeee 8%, #dddddd 18%, #eeeeee 33%);
background-size: 800px 104px;
height: 40px;
position: relative;
}
@keyframes placeHolderShimmer{
0% {
background-position: -468px 0
}
100% {
background-position: 468px 0
}
}
</style>
2, 使用方式
1, 引入组建后, template 标签内加入
<skeleton selector="skeleton" bgcolor="#FFF" v-if="showSkeleton"></skeleton>
- 其中
v-if="showSkeleton"
为显示骨架屏显示的参数。
2, data
对象中设置showSkeleton: true
// 默认一开始进入页面加载骨架屏内容。
- 骨架屏渲染形状有两种:矩形 & 圆形
- 在想显示骨架屏的区域的父级标签的
class
加入skeleton
表示该class下的内容进行骨架屏元素加载 - 需要
渲染
矩形,则在该元素上的class加入skeleton-rect
- 需要
圆形
矩形,则在该元素上的class加入skeleton-radius
3, 渲染数据。
- 渲染骨架屏的元素,需要先填充元素。使vue能够根据数据的长度进行渲染。
- 列表类数据 字段值可为空。例如:
dataList: [
{
title: '',
author: '',
pubTime: '',
avatar: ''
},
{
title: '',
author: '',
pubTime: '',
avatar: ''
}
]
- 此时会渲染两条数据内容
4,关闭骨架屏效果
- 待数据请求到本地后,将
showSkeleton = false
即可。否则骨架屏层级过高(当然也可更改插件的z-index: 9998;)。数据视图将被覆盖