您现在的位置是:网站首页>前端技术>VueVue
VUE实现骨架屏,uniapp骨架屏,小程序骨架屏效果实现
神夜2020-05-26 11:10:54【Vue】3728人已围观文章来源:神夜个人博客
简介skeleton.vue 插件适用于VUE项目和uniapp小程序H5项目。使用简单
1、首先编写一个skeleton.vue 插件 代码如下,参考别人编写生成uniapp改了一下。
<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='index' class="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="'info2-'+index" class="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> export default { props: { bgcolor: { type: String, value: '#FFF' }, selector: { type: String, value: 'skeleton' }, }, data() { return { systemInfo: {}, skeletonRectLists: [], skeletonCircleLists: [], }; }, components: {}, mounted: function() { //默认的首屏宽高,防止内容闪现 this.systemInfo = { width: window.innerWidth, height: window.innerHeight, }; var dom = document.querySelectorAll(`.$ { this.selector }`); //this.systemInfo.height = dom[0].clientHeight + dom[0].offsetTop || 0; //绘制矩形 this.rectHandle(); //绘制圆形 this.radiusHandle(); }, methods: { //绘制距形 rectHandle: function() { let dom = document.querySelectorAll(`.$ { this.selector } - rect`); for (var i = 0; i < dom.length; i++) { this.skeletonRectLists.push(dom[i].getBoundingClientRect()); } }, //绘制圆形 radiusHandle: function() { let dom = document.querySelectorAll(`.$ { this.selector } - radius`); for (var i = 0; i < dom.length; i++) { this.skeletonCircleLists.push(dom[i].getBoundingClientRect()) } }, }, }; </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>
如果将代码改一下可以用于UNIAPP小程序和公众号
<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='index' class="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="'info2-'+index" class="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' }, }, data() { return { systemInfo: {}, skeletonRectLists: [], skeletonCircleLists: [], }; }, components: {}, mounted: function() { //默认的首屏宽高,防止内容闪现 const systemInfo = uni.getSystemInfoSync(); (this.systemInfo = { width: systemInfo.windowWidth, height: systemInfo.windowHeight, }); const that = this; //绘制背景 uni .createSelectorQuery() .selectAll(`.${this.selector}`) .boundingClientRect() .exec(function(res) { console.log(res); that.systemInfo.height = res[0][0].height + res[0][0].top || 0; }); //绘制矩形 this.rectHandle(); //绘制圆形 this.radiusHandle(); }, methods: { rectHandle: function() { const that = this; //绘制不带样式的节点 uni .createSelectorQuery() .selectAll(`.${this.selector}-rect`) .boundingClientRect() .exec(function(res) { that.skeletonRectLists = res[0]; }); }, radiusHandle: function() { const that = this; uni .createSelectorQuery() .selectAll(`.${this.selector}-radius`) .boundingClientRect() .exec(function(res) { console.log(res[0].length); that.skeletonCircleLists = res[0]; }); }, }, }; /* 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、调用插件 skeleton.vue
<template> <div class="content "> <skeleton selector="skeleton" bgcolor="#FFF" v-if="showSkeleton"></skeleton> <div class="skeleton"> <img class="logo skeleton-rect" src="/static/logo.png"> <div class="text-area skeleton-radius"> <div class="title">{{ title }}</div> </div> </div> </div> </template> <script> import skeleton from '@/pages/index/skeleton.vue' export default { data() { return { showSkeleton: true, title: 'Hello', } }, components: { 'skeleton': skeleton }, created() { this.reloadData(); }, methods: { reloadData() { setTimeout(() = >{ this.showSkeleton = false }, 2000) }, } } </script>
注意:显示距形:则在样式上添加 skeleton-rect, 显示圆形 :skeleton-radius , 如果没有添加这两个样式,则是一片空白
实现原理:根据原有的DIV 宽和高以及left和top 来绘制一个空白div。循环生成多个div 再给DIV加上样式动画。设置时间 多少秒后消失。
本栏推荐

猜你喜欢
站点信息
- 建站时间:2017-10-24
- 网站程序:Hsycms 3.0
- 文章统计:511条
- 微信公众号:扫描二维码,关注我们
