3.27 Skeleton 骨架屏

简介

骨架屏组件Skeleton 常用于在需要等待加载内容的位置提供一个占位图形组合,可以被 Loading 完全代替,但是在可用的场景下可以提供更好的视觉效果和用户体验。

  • 网络较慢,需要长时间等待加载处理的情况下。

  • 图文信息内容较多的列表/卡片中。

  • 只在第一次加载数据的时候使用

本文将分析其源码实现,耐心读完,相信会对您有所帮助。🔗 组件文档 Skeleton 🔗 gitee源码

更多组件剖析详见 👉 📚 Element 2 源码剖析组件总览 。。

组件源码

组件的 prop 声明,各属性功能说明详见官方文档skeleton#attributes

根组件 index.vue

根组件定义了两个部分,用于加载占位和真实DOM之间的切换:

  1. 用于展示骨架屏,提供具名template插槽用于自定义占位符。

  2. 用于展示真实组件UI,使用匿名插槽。

组件使用了v-bind="$attrs"实现了透传Attributes,用于父子组件的Attributes 继承。

// packages\skeleton\src\index.vue
<template>
  <div> 
    <template v-if="uiLoading">
      <!-- 展示骨架屏 -->
      <div :class="['el-skeleton', animated ? 'is-animated' : '', ]" v-bind="$attrs">
        <template v-for="i in count">
          <!-- 展示自定义占位符 -->
          <slot v-if="loading" name="template">
            <el-skeleton-item v-for="item in rows" variant="p"/>
          </slot>
        </template>
      </div>
    </template>
    <template v-else>
      <!-- 展示真实 UI -->
      <slot v-bind="$attrs"></slot>
    </template>
  </div>
</template>

骨架屏占位元素渲染通过内部属性uiLoading进行控制,该属性逻辑稍后详细介绍。

属性animated 用于生成样式类is-animated,控制占位元素是否动画效果。

占位元素渲染

默认情况下组件会渲染一条记录(属性count默认值为1),包含四个占位元素(属性rows默认值为4),默认为标签p样式。

首行会被渲染一个长度 33% 的段首;多行时末行会被渲染一个长度 61% 的段尾。

渲染效果如下图:

image.png

当渲染多条数据时,若未未自定义占位元素,会出现相邻记录的段尾和段首会出现在一行中(因为使用了<template> 标签),渲染结果如下:

image.png

当需要使用骨架屏渲染列表时,才会将 count 设置为多条。

组件生命周期&事件

组件的显示状态uiLoading根据属性throttleloading传入值动态设置。 当属性 throttle 值大于0,开启延迟渲染占位元素,侦听器会进行不同逻辑处理。

当 API 的请求回来的特别快,往往骨架占位刚刚被渲染,真实的数据就已经回来了,用户的界面会突然一闪,此时为了避免这种情况,就需要通过 throttle 属性来避免这个问题。

占位元素组件 item.vue

占位元素组件el-skeleton-item支持多种标签 p/text/h1/h3/text/caption/button/image/circle/rect 的样式。

各标签样式渲染效果如下,支持样式自定义:

image.png

当需要渲染标签image样式时使用 svg 图标组件img-placeholder

组件渲染效果如下:

image.png

样式实现

组件样式源码 packages\theme-chalk\src\skeleton.scss 使用混合指令嵌套生成组件样式。

组件样式源码 packages\theme-chalk\src\skeleton-item.scss 使用混合指令嵌套生成组件样式。

按照样式声明,也可以使用标签 h5 样式。圆形虽然定义了不同尺寸,但是组件未提供接口。

📚参考&关联阅读

'透传Attributes',vuejs

最后更新于