用于小程序中的骨架屏

基于uni-app的一个骨架屏插件。

在使用的时候可以直接在components中引入组件quick-skeleton.vue。组件代码如下:

  1 <template>
  2     <view
  3         v-show="show"
  4         :style="{
  5             width: systemInfo.width + ‘px‘,
  6             height: systemInfo.height + ‘px‘,
  7             backgroundColor: bgcolor,
  8             position: ‘absolute‘,
  9             left: 0,
 10             top: 0,
 11             zIndex: 9998,
 12             overflow: ‘hidden‘
 13         }"
 14     >
 15         <view
 16             v-for="(item, rect_idx) in skeletonRectLists"
 17             :key="rect_idx + ‘rect‘"
 18             :class="[loading == ‘chiaroscuro‘ ? ‘chiaroscuro‘ : ‘‘]"
 19             :style="{
 20                 width: item.width + ‘px‘,
 21                 height: item.height + ‘px‘,
 22                 backgroundColor: ‘#f4f4f‘,
 23                 position: ‘absolute‘,
 24                 left: item.left + ‘px‘,
 25                 top: item.top + ‘px‘
 26             }"
 27         ></view>
 28         <view
 29             v-for="(item, circle_idx) in skeletonCircleLists"
 30             :key="circle_idx + ‘circle‘"
 31             :class="loading == ‘chiaroscuro‘ ? ‘chiaroscuro‘ : ‘‘"
 32             :style="{
 33                 width: item.width + ‘px‘,
 34                 height: item.height + ‘px‘,
 35                 backgroundColor: ‘#f4f4f‘,
 36                 borderRadius: item.width + ‘px‘,
 37                 position: ‘absolute‘,
 38                 left: item.left + ‘px‘,
 39                 top: item.top + ‘px‘
 40             }"
 41         ></view>
 42
 43         <view class="spinbox" v-if="loading == ‘spin‘"><view class="spin"></view></view>
 44     </view>
 45 </template>
 46
 47 <script>
 48 export default {
 49     name: ‘skeleton‘,
 50     props: {
 51         bgcolor: {
 52             type: String,
 53             value: ‘#FFF‘
 54         },
 55         selector: {
 56             type: String,
 57             value: ‘skeleton‘
 58         },
 59         loading: {
 60             type: String,
 61             value: ‘spin‘
 62         },
 63         show: {
 64             type: Boolean,
 65             value: false
 66         }
 67     },
 68     data() {
 69         return {
 70             loadingAni: [‘spin‘, ‘chiaroscuro‘],
 71             systemInfo: {},
 72             skeletonRectLists: [],
 73             skeletonCircleLists: []
 74         };
 75     },
 76     watch: {
 77         show() {
 78             this.attachedAction();
 79             this.readyAction();
 80         }
 81     },
 82     methods: {
 83         attachedAction: function() {
 84             //默认的首屏宽高,防止内容闪现
 85             const systemInfo = uni.getSystemInfoSync();
 86             this.systemInfo = {
 87                 width: 750,
 88                 height: 1440
 89             };
 90             this.loading = this.loadingAni.includes(this.loading) ? this.loading : ‘spin‘;
 91         },
 92         readyAction: function() {
 93             const that = this;
 94             //绘制背景
 95             uni.createSelectorQuery()
 96                 .selectAll(`.${this.selector}`)
 97                 .boundingClientRect()
 98                 .exec(function(res) {
 99                     that.systemInfo.height = res[0][0].height + res[0][0].top;
100                 });
101
102             //绘制矩形
103             this.rectHandle();
104
105             //绘制圆形
106             this.radiusHandle();
107         },
108         rectHandle: function() {
109             const that = this;
110
111             //绘制不带样式的节点
112             uni.createSelectorQuery()
113                 .selectAll(`.${this.selector}-rect`)
114                 .boundingClientRect()
115                 .exec(function(res) {
116                     that.skeletonRectLists = res[0];
117                 });
118         },
119         radiusHandle() {
120             const that = this;
121
122             uni.createSelectorQuery()
123                 .selectAll(`.${this.selector}-radius`)
124                 .boundingClientRect()
125                 .exec(function(res) {
126                     that.skeletonCircleLists = res[0];
127                 });
128         }
129     }
130 };
131 </script>
132
133 <style>
134 .spinbox {
135     position: fixed;
136     display: flex;
137     justify-content: center;
138     align-items: center;
139     height: 100%;
140     width: 100%;
141     z-index: 9999;
142 }
143 .spin {
144     display: inline-block;
145     width: 64rpx;
146     height: 64rpx;
147 }
148 .spin:after {
149     content: ‘ ‘;
150     display: block;
151     width: 46rpx;
152     height: 46rpx;
153     margin: 1rpx;
154     border-radius: 50%;
155     border: 5rpx solid #409eff;
156     border-color: #409eff transparent #409eff transparent;
157     animation: spin 1.2s linear infinite;
158 }
159 @keyframes spin {
160     0% {
161         transform: rotate(0deg);
162     }
163     100% {
164         transform: rotate(360deg);
165     }
166 }
167
168 .chiaroscuro {
169     width: 100%;
170     height: 100%;
171     background: #f4f4f4;
172     animation-duration: 2s;
173     animation-name: blink;
174     animation-iteration-count: infinite;
175 }
176
177 @keyframes blink {
178     0% {
179         opacity: 0.5;
180     }
181     50% {
182         opacity: 1;
183     }
184     100% {
185         opacity: 0.5;
186     }
187 }
188
189 @keyframes flush {
190     0% {
191         left: -100%;
192     }
193     50% {
194         left: 0;
195     }
196     100% {
197         left: 100%;
198     }
199 }
200 .shine {
201     animation: flush 2s linear infinite;
202     position: absolute;
203     top: 0;
204     bottom: 0;
205     width: 100%;
206     background: linear-gradient(to left, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.85) 50%, rgba(255, 255, 255, 0) 100%);
207 }
208 </style>

引入代码后,在需要加载骨架屏的页面中,为整个页面的盒子加一类名skeleton,并加一个兄弟节点quick-skeleton引入组件:

showSkeleton控制骨架屏是否显示;

骨架屏显示时catchtouchmove和fixed控制页面是否可以滑动,这里用fixed让页面不可滑动;

bgcolor为骨架屏的背景颜色。其余属性不需改动,可以直接使用。

在onReady()中控制骨架屏的加载,

若是即时加载的骨架屏,可以将_this.showSkeleton = false;放在接口调用成功之后,这样就实现了加载完后骨架屏自动消失的效果,这里暂用定时器来实现骨架屏的隐藏。

 1 <view>
 2     <quick-skeleton
 3         :show="showSkeleton"
 4         ref="skeleton"
 5         catchtouchmove="true"
 6         fixed="true"
 7         loading="chiaroscuro"
 8         selector="skeleton"
 9         bgcolor="#FFF"
10         style="overflow: hidden;"
11     ></quick-skeleton>
12     <div class="page-content skeleton"></div>
13 </view>
14 <script>
15     import quickSkeleton from ‘../../components/quick-skeleton.vue‘;
16     export default {
17         data() {
18             return {
19                 showSkeleton: true,
20             };
21         },
22         components: {
23             quickSkeleton
24         },
25         onReady() {
26             let _this = this;
27             _this.$refs.skeleton.attachedAction();
28             _this.$refs.skeleton.readyAction();
29             setTimeout(function() {
30                 _this.showSkeleton = false;
31             }, 3000);
32         },
33     }
34 </script>

然后只要在页面中为想要生成骨架屏的元素加类名即可:

skeleton-radius表示圆形,skeleton-rect表示矩形

注:如果是利用v-for动态生成的结构,不能自动生成骨架屏,所以这里写出结构模板,给模板元素固定的宽高和背景颜色(与骨架屏相同),再用showSkeleton控制页面加载完成后隐藏结构模板。

 1 <div v-show="showSkeleton">
 2     <navigator hover-class="none" class="">
 3         <div class="">
 4             <div class="skeleton-radius" style="background: #f5f6f7;"><img class="" mode="" /></div>
 5             <div class="">
 6                 <span class="skeleton-rect" style="background: #f5f6f7;height: 26px;"></span>
 7                 <div class="skeleton-rect" style="background: #f5f6f7;height: 15px;"></div>
 8             </div>
 9         </div>
10         <ul class="skeleton-rect" style="background: #f5f6f7;"></ul>
11         <ul class="skeleton-rect" style="background: #f5f6f7;">
12             <li class=""><img class="" mode="" /></li>
13             <li class=""><img class="" mode="" /></li>
14             <li class=""><img class="" mode="" /></li>
15         </ul>
16         <div class="skeleton-rect" style="background: #f5f6f7;height: 20px;"></div>
17     </navigator>
18 </div>

此骨架屏为颜色渐浅的闪烁效果,如果想要修改的话只需在组件中修改css。

效果如下:

原文地址:https://www.cnblogs.com/cnlisiyiii-stu/p/11969581.html

时间: 2024-11-11 20:40:26

用于小程序中的骨架屏的相关文章

【小程序】小程序性能探索----骨架屏

骨架屏是什么? 在Goole提出的以用户为中心的四个页面性能衡量指标中,FP/FCP(首屏渲染). 关于尽快渲染出首屏,减少白屏时间,常见的优化方式大致有以下几种: 1. 优化关键渲染路径,尽可能减少阻塞渲染的JavaScript和CSS,常见做法包括使用async/defer让浏览器下载JavaScript的同时不阻塞HTML解析,内联页面关键部分的 样式 2. 使用Service Worker 缓存AppShell,加快后续访问速度. 3. 使用HTTP/2 Server Push,帮助浏览

浅谈高大上的微信小程序中渲染html内容—技术分享

大部分Web应用的富文本内容都是以HTML字符串的形式存储的,通过HTML文档去展示HTML内容自然没有问题.但是,在微信小程序(下文简称为「小程序」)中,应当如何渲染这部分内容呢? 解决方案 wxParse 小程序刚上线那会儿,是无法直接渲染HTML内容的,于是就诞生了一个叫做「 wxParse 」的库.它的原理就是把HTML代码解析成树结构的数据,再通过小程序的模板把该数据渲染出来. rich-text 前端精品教程:百度网盘下载 后来,小程序增加了「rich-text」组件用于展示富文本内

WePY 在手机充值小程序中的应用与实践

wepyjs 发布了两个月了,中间经历了很多版本更新,也慢慢开始有一些用户选择 wepyjs 作为开发框架来开发小程序,比如一些线上小程序. 以及一些来自网上的 wepyjs 的相关资源: demo源码: one,图书管理系统 组件:图表控件 因此我也将手机充值小程序在开发过程中 wepyjs 的应用心得分享出来,可以参照对比与传统小程序开发上的差异. 说明:本文不涉及到 wepyjs 的使用与说明,如果需要请参看我的另一篇文章 "打造小程序组件化开发框架" 或直接参看wepyjs 项

小程序中的setData的使用

小程序中的setData setData 函数用于将数据从逻辑层发送到视图层(异步),同时改变对应的 this.data 的值(同步). 直接修改 this.data 而不调用 this.setData 是无法改变页面的状态的,还会造成数据不一致. 单次设置的数据不能超过1024kB,请尽量避免一次设置过多的数据. 示例代码: index.wxml <view>{{name}}</view> <button bindtap="changeName">

在微信小程序中使用redux

本文主要讲述,在微信小程序中如何使用redux DEMO 需要解决的问题 如何在小程序中引入redux状态管理库,及它相关的插件? 微信小程序没有清晰的异步api,便于thunkMiddleware处理异步请求(异步操作),如何解决? 如何正确使用store的三大核心方法(getStore dispatch subscribe)? redux并不是react专属,所以他可以在任何地方使用,小程序也不例外.解决上面三个问题就可以了. 问题一: 如何在小程序中引入redux状态管理库,及它相关的插件

去除富文本中的html标签及vue、react、微信小程序中的过滤器

在获取富文本后,又只要显示部分内容,需要去除富文本标签,然后再截取其中一部分内容:然后就是过滤器,在微信小程序中使用还是挺多次的,在vue及react中也遇到过 1.富文本去除html标签 去除html标签及?空格 let richText = ' <p style="font-size: 25px;color: white">&nbsp; &nbsp; &nbsp; &nbsp;sdaflsjf的丰富及饿哦塞尔</p><s

全栈开发工程师微信小程序-中(中)

开放能力 open-data 用于展示微信开放的数据 type 开放数据类型 open-gid 当 type="groupName" 时生效, 群id lang 当 type="user*" 时生效,以哪种语言展示 userInfo <open-data type="groupName" open-gid="xxxxxx"></open-data> <open-data type="us

Senparc.Weixin.MP SDK 微信公众平台开发教程(二十一):在小程序中使用 WebSocket (.NET Core)

本文将介绍如何在 .NET Core 环境下,借助 SignalR 在小程序内使用 WebSocket.关于 WebSocket 和 SignalR 的基础理论知识不在这里展开,已经有足够的参考资料,例如参考 SignalR 的官方教程:https://docs.microsoft.com/zh-cn/aspnet/core/signalr/introduction?view=aspnetcore-2.1 我们先看一下完成本教程内容后,在小程序内实现的 WebSocket 效果: 私有及群发消息

「wxParser」小程序插件:想在小程序中快速部署富文本?这个插件让你一步搞定

上期,我们在<「微信同声传译」小程序插件:快速实现语音转文字.文本翻译.语音合成等能力>一文中介绍了「微信同声传译」小程序插件的意义.作用以及应用.而在此之前,我们还介绍过「腾讯地图」.「腾讯视频」.「医院 LBS 位置服务」插件,有兴趣了解的读者可以点击「微信极客WeGeek」公众号底部菜单「极客干货 - 小程序插件」了解. 今天我们为大家推荐的是一款富文本渲染插件「wxParser」,目前 wxParser 支持对一般的富文本内容包括标题.字体大小.对齐和列表等进行解析.同时也支持表格.代