tui-skeleton

tui-skeleton 骨架屏,数据请求时常见到锁屏的loading动画,而现在越来越多的产品倾向于使用Skeleton Screen替代 。

组件结构

  1. <viewclass="tui-skeleton-cmomon tui-skeleton-box" :style="{width: winWidth+'px', height:winHeight+'px', backgroundColor:backgroundColor}">
  2. <viewclass="tui-skeleton-cmomon"v-for="(item,index) in skeletonElements" :key="index" :style="{width: item.width+'px', height:item.height+'px', left: item.left+'px', top: item.top+'px',backgroundColor: skeletonBgColor,borderRadius:getRadius(item.skeletonType,borderRadius)}"></view>
  3. <viewclass="tui-loading" :class="[getLoadingType(loadingType)]"v-if="isLoading"></view>
  4. </view>

组件脚本

  1. <script>
  2. exportdefault{
  3. name:"tuiSkeleton",
  4. props:{
  5. //选择器(外层容器)
  6. selector:{
  7. type:String,
  8. default:"tui-skeleton"
  9. },
  10. //外层容器背景颜色
  11. backgroundColor:{
  12. type:String,
  13. default:"#fff"
  14. },
  15. //骨架元素背景颜色
  16. skeletonBgColor:{
  17. type:String,
  18. default:"#e9e9e9"
  19. },
  20. //骨架元素类型:矩形,圆形,带圆角矩形["rect","circular","fillet"]
  21. //默认所有,根据页面情况进行传值
  22. //页面对应元素class为:tui-skeleton-rect,tui-skeleton-circular,tui-skeleton-fillet
  23. //如果传入的值不在下列数组中,则为自定义class值,默认按矩形渲染
  24. skeletonType:{
  25. type:Array,
  26. default(){
  27. return["rect","circular","fillet"]
  28. }
  29. },
  30. //圆角值,skeletonType=fillet时生效
  31. borderRadius:{
  32. type:String,
  33. default:"16rpx"
  34. },
  35. //骨架屏预生成数据:提前生成好的数据,当传入该属性值时,则不会再次查找子节点信息
  36. preloadData:{
  37. type:Array,
  38. default(){
  39. return[]
  40. }
  41. },
  42. //是否需要loading
  43. isLoading:{
  44. type:Boolean,
  45. default:true
  46. },
  47. //loading类型[1-10]
  48. loadingType:{
  49. type:Number,
  50. default:1
  51. }
  52. },
  53. created(){
  54. const res = uni.getSystemInfoSync();
  55. this.winWidth = res.windowWidth;
  56. this.winHeight = res.windowHeight;
  57. //如果有预生成数据,则直接使用
  58. this.isPreload(true)
  59. },
  60. // #ifdef H5
  61. mounted(){
  62. this.$nextTick(()=>{
  63. this.nodesRef(`.${this.selector}`).then((res)=>{
  64. this.winHeight = res[0].height +Math.abs(res[0].top)
  65. });
  66. !this.isPreload()&&this.selectorQuery()
  67. })
  68. },
  69. // #endif
  70. onReady(){
  71. this.nodesRef(`.${this.selector}`).then((res)=>{
  72. this.winHeight = res[0].height +Math.abs(res[0].top)
  73. });
  74. !this.isPreload()&&this.selectorQuery()
  75. },
  76. data(){
  77. return{
  78. winWidth:375,
  79. winHeight:800,
  80. skeletonElements:[]
  81. };
  82. },
  83. methods:{
  84. getLoadingType:function(type){
  85. let value =1
  86. if(type && type >0&& type <11){
  87. value = type
  88. }
  89. return'tui-loading-'+ value
  90. },
  91. getRadius:function(type, val){
  92. let radius ="0"
  93. if(type =="circular"){
  94. radius ="50%"
  95. }elseif(type =="fillet"){
  96. radius = val
  97. }
  98. return radius;
  99. },
  100. isPreload(init){
  101. let preloadData =this.preloadData ||[]
  102. if(preloadData.length){
  103. init &&(this.skeletonElements = preloadData)
  104. returntrue
  105. }
  106. returnfalse
  107. },
  108. async selectorQuery(){
  109. let skeletonType =this.skeletonType ||[]
  110. let nodes =[]
  111. for(let item of skeletonType){
  112. let className =`.${this.selector}>>>.${item}`
  113. // #ifdef H5
  114. className =`.${item}`
  115. // #endif
  116. if(~"rect_circular_fillet".indexOf(item)){
  117. // #ifndef H5
  118. className =`.${this.selector}>>>.${this.selector}-${item}`
  119. // #endif
  120. // #ifdef H5
  121. className =`.${this.selector}-${item}`
  122. // #endif
  123. }
  124. await this.nodesRef(className).then((res)=>{
  125. res.map(d =>{
  126. d.skeletonType = item
  127. })
  128. nodes = nodes.concat(res)
  129. })
  130. }
  131. this.skeletonElements = nodes
  132. },
  133. async nodesRef(className){
  134. return await newPromise((resolve, reject)=>{
  135. uni.createSelectorQuery().selectAll(className).boundingClientRect((res)=>{
  136. if(res){
  137. resolve(res);
  138. }else{
  139. reject(res)
  140. }
  141. }).exec();
  142. })
  143. }
  144. }
  145. }
  146. </script>

组件样式

... 此处省略n行

脚本说明

props

参数类型描述默认值
selectorString选择器(外层容器)tui-skeleton
backgroundColorString外层容器背景颜色#fff
skeletonBgColorString骨架元素背景颜色#e9e9e9
skeletonTypeArray骨架元素类型:矩形,圆形,带圆角矩形["rect", "circular", "fillet"]
borderRadiusString圆角值,skeletonType=fillet时生效16rpx
preloadDataArray骨架屏预生成数据[]
isLoadingBoolean是否需要loadingtrue
loadingTypeNumberloading类型[1-10]1

methods

名称描述
getLoadingType获取loading类型
getRadius获取圆角值
isPreload骨架屏是否有预生成数据
selectorQuery查找骨架元素节点
nodesRef查找骨架元素节点api执行

示例

... 此处省略n行,下载源码查看

预览图

#

tui-skeleton 骨架屏 - 图1