Vue灵活骨架屏组件封装

1,757 阅读2分钟

骨架屏,就要精准定制才行


组件源码及其完整示例,戳这里👇👇👇👇👇

PC观看示例更佳

示例戳这里

源码戳这里


关于骨架屏概念

骨架屏,其实就给用户展示一个页面的大体骨架,不会让用户有等待时间过长的感觉。实际也比菊花式加载用户体验也会好很多



我的骨架屏解决方案

既然是骨架屏,作为一个用户视觉缓冲工具,很多地方可能会用。为了实现简单,我封装了一个骨架屏的组件。


原理

使用者将想要的布局封装为一个树状的数据结构,然后让组件去递归解析

在这里,我使用了Vue的递归组件。


<template>  
   <div class="skeleton-wrapper">    
     <div class="skeleton-content">     
       <item :paragraph="paragraph" :active="active"></item>    
     </div>  
   </div>
</template>


let template =  `
      <div>
         <div v-if="paragraph.type === 'row'"            
           :class="paragraph.containerClass"            
           class="ske-row-container">          
           <div class="ske ske-row"               
                :style="row.rowStyle"               
                v-for="row in paragraph.rows"> 
                <item :paragraph="row" :active="active"></item> 
           </div>
         </div>      
         <div v-else-if="paragraph.type === 'col'" 
              :class="paragraph.containerClass"     
              class="ske-col-container">    
              <div class="ske ske-col"        
                   :style="col.colStyle"      
                   v-for="col in paragraph.cols">         
                   <item :paragraph="col" :active="active"></item>   
              </div>   
         </div>    
         <div v-else-if="paragraph.type === 'rect'"  
              :class="paragraph.containerClass"      
              class="ske-rect-container">  
              <div class="ske ske-rect"           
                   :class="{'ske-ani': active}"         
                   :style="paragraph.style"></div>  
         </div>   
        <div v-else-if="paragraph.type === 'circle'"      
             :class="paragraph.containerClass"      
             class="ske-circle-container">         
             <div class="ske ske-circle"         
                  :class="{'ske-ani': active}"            
                  :style="paragraph.style"> </div>    
        </div>  
     </div>`;

Vue.component('item', {
    name: "item",
    template: template,
    props: ["paragraph", "active"]
});

通过解析一个树状的数据结构,进行递归调用渲染。最后渲染出整个骨架屏。



数据结构方面,可以把一个整体分割开来。像上面的那个示例,我可以把它分为4行(row)。

然后每一行里面,分别有一条矩形。矩形的css我也可以定义



像这一个,可以把它分割为两列(col)。然后第一列里,有一个圆形。第二列里则有两个row(行)。上下两行也是两条矩形。

行里面可以嵌套列,列里面也可以嵌套行。但是圆形/矩形里面就不可嵌套东西了

示例:




有哪些属性?

目前仅支持 paragraph  和 active 两个属性。

  • paragraph:骨架屏的数据,是一个标准格式的数据对象
  • active:是否开启动画


paragraph Object

参数说明类型可选值默认值
type父容器类型stringcol / row / rectangle / circlenone
cols / rows子模块数组Array-false
style矩形/圆形 主体的样式Object-{}
rowStyle / colStyle矩形/圆形的主体其外部盒子的样式Object-{}