|
|
<template> <view v-if="show" :style="{width: systemInfo.width + 'px', height: systemInfo.height + 'px', backgroundColor: bgcolor, position: 'absolute', left: 0, top: 0, zIndex: 9998}"> <view v-for="(item,rect_idx) in skeletonRectLists" :key="rect_idx + 'rect'" :class="[loading == 'chiaroscuro' ? 'chiaroscuro' : '']" :style="{width: item.width + 'px', height: item.height + 'px', backgroundColor: 'rgb(194, 207, 214,.3)', position: 'absolute', left: item.left + 'px', top: item.top + 'px'}"> </view> <view v-for="(item,circle_idx) in skeletonCircleLists" :key="circle_idx + 'circle'" :class="loading == 'chiaroscuro' ? 'chiaroscuro' : ''" :style="{width: item.width + 'px', height: item.height + 'px', backgroundColor: 'rgb(194, 207, 214,.3)', borderRadius: item.width + 'px', position: 'absolute', left: item.left + 'px', top: item.top + 'px'}"> </view> <view class="spinbox" v-if="loading == 'spin'"> <view class="spin"></view> </view> </view></template>
<script> export default { name: "skeleton", props: { bgcolor: { type: String, value: '#FFF' }, selector: { type: String, value: 'skeleton' }, loading: { type: String, value: 'spin' }, show: { type: Boolean, value: false }, isNodes: { type: Number, value: false } //控制什么时候开始抓取元素节点,只要数值改变就重新抓取
}, data() { return { loadingAni: ['spin', 'chiaroscuro'], systemInfo: {}, skeletonRectLists: [], skeletonCircleLists: [] } }, watch: { isNodes(val) { this.readyAction(); } }, mounted() { this.attachedAction(); }, methods: { attachedAction: function() { //默认的首屏宽高,防止内容闪现
const systemInfo = uni.getSystemInfoSync(); this.systemInfo = { width: systemInfo.windowWidth, height: systemInfo.windowHeight }; this.loading = this.loadingAni.includes(this.loading) ? this.loading : 'spin'; }, readyAction: function() { const that = this; //绘制背景
uni.createSelectorQuery().selectAll(`.${this.selector}`).boundingClientRect().exec(function(res) { if(res[0].length>0) that.systemInfo.height = res[0][0].height + res[0][0].top; });
//绘制矩形
this.rectHandle();
//绘制圆形
this.radiusHandle(); }, rectHandle: function() { const that = this;
//绘制不带样式的节点
uni.createSelectorQuery().selectAll(`.${this.selector}-rect`).boundingClientRect().exec(function(res) { that.skeletonRectLists = res[0]; });
}, radiusHandle() { const that = this;
uni.createSelectorQuery().selectAll(`.${this.selector}-radius`).boundingClientRect().exec(function(res) { that.skeletonCircleLists = res[0]; }); } } }</script>
<style> .spinbox { position: fixed; display: flex; justify-content: center; align-items: center; height: 100%; width: 100%; z-index: 9999 }
.spin { display: inline-block; width: 64rpx; height: 64rpx; }
.spin:after { content: " "; display: block; width: 46rpx; height: 46rpx; margin: 1rpx; border-radius: 50%; border: 5rpx solid #409eff; border-color: #409eff transparent #409eff transparent; animation: spin 1.2s linear infinite; }
@keyframes spin { 0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); } }
.chiaroscuro { width: 100%; height: 100%; background: rgb(194, 207, 214); animation-duration: 2s; animation-name: blink; animation-iteration-count: infinite; }
@keyframes blink { 0% { opacity: .4; }
50% { opacity: 1; }
100% { opacity: .4; } }
@keyframes flush { 0% { left: -100%; }
50% { left: 0; }
100% { left: 100%; } }
.shine { animation: flush 2s linear infinite; position: absolute; top: 0; bottom: 0; width: 100%; background: linear-gradient(to left, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, .85) 50%, rgba(255, 255, 255, 0) 100%) }</style>
|