Skeleton 骨架屏
在需要等待加载内容的位置展示占位结构。相比 Loading,骨架屏更能保持页面布局稳定,适合列表、详情卡片、表格和异步内容区域。
基础用法
直接使用 el-skeleton 可以渲染默认骨架段落。通过 template 插槽和 el-skeleton-item 可以声明圆形、图片、文本等占位形态。
vue
<el-skeleton />
<el-skeleton style="--el-skeleton-circle-size: 72px">
<template #template>
<el-skeleton-item variant="circle" />
</template>
</el-skeleton>更多参数
通过 rows 可以配置骨架段落数量。为了更接近真实排版,首行会渲染为较短的段首。
vue
<el-skeleton :rows="5" />动画效果
设置 animated 后,骨架屏会显示加载动画,适合等待时间稍长的异步区域。
vue
<el-skeleton :rows="5" animated />自定义样式
通过 template 插槽可以自定义骨架结构。自定义模板应尽量贴近真实 DOM 的尺寸,避免真实内容渲染后发生明显抖动。
vue
<el-skeleton style="width: 280px" animated>
<template #template>
<el-skeleton-item variant="image" style="width: 280px; height: 160px" />
<div style="padding: 14px">
<el-skeleton-item variant="h3" style="width: 50%" />
<div style="display: flex; gap: 16px; margin-top: 16px">
<el-skeleton-item variant="text" />
<el-skeleton-item variant="text" style="width: 32%" />
</div>
<el-skeleton-item variant="button" style="width: 96px" />
</div>
</template>
</el-skeleton>加载状态
通过 loading 控制是否展示骨架屏。加载结束后,default 插槽中的真实内容会被渲染出来。
vue
<template>
<el-switch v-model="loading" />
<el-skeleton style="width: 280px" :loading="loading" animated>
<template #template>
<el-skeleton-item variant="image" style="width: 280px; height: 160px" />
<div style="padding: 14px">
<el-skeleton-item variant="h3" style="width: 50%" />
<el-skeleton-item variant="text" />
</div>
</template>
<template #default>
<el-card>真实内容</el-card>
</template>
</el-skeleton>
</template>
<script setup lang="ts">
import { ref } from 'vue'
const loading = ref(true)
</script>渲染多条数据
列表加载时,可以通过 count 控制渲染多少条骨架模板。为了体验和性能,count 不宜过大。
vue
<template>
<el-button @click="reload">重新加载</el-button>
<el-skeleton :loading="loading" animated :count="3">
<template #template>
<el-skeleton-item variant="image" style="height: 120px" />
<el-skeleton-item variant="h3" style="width: 60%" />
</template>
<template #default>
<el-card v-for="item in list" :key="item.name">{{ item.name }}</el-card>
</template>
</el-skeleton>
</template>防止渲染抖动
当接口响应很快时,骨架屏可能刚显示就被真实内容替换,造成闪烁。通过 throttle 可以延迟显示或延迟隐藏骨架。
vue
<el-skeleton :loading="loading" animated :throttle="500">
<template #template>
<el-skeleton-item variant="image" style="height: 160px" />
<el-skeleton-item variant="h3" />
</template>
<template #default>
<el-card>加载完成</el-card>
</template>
</el-skeleton>初始渲染加载
当初始状态就是加载中时,可以设置 throttle="{ leading, initVal }",让初始骨架立即显示,并控制后续切换节奏。
vue
<el-skeleton
:loading="loading"
animated
:throttle="{ leading: 500, initVal: true }"
>
<template #template>
<el-skeleton-item variant="image" style="height: 160px" />
</template>
<template #default>
<el-card>初始加载完成</el-card>
</template>
</el-skeleton>平滑切换
throttle 也可以同时设置 leading 与 trailing,分别控制骨架显示和消失节奏,让加载状态切换更平滑。
vue
<el-skeleton
:loading="loading"
animated
:throttle="{ leading: 500, trailing: 500, initVal: true }"
>
<template #template>
<el-skeleton-item variant="image" style="height: 160px" />
</template>
<template #default>
<el-card>平滑切换</el-card>
</template>
</el-skeleton>Skeleton API
Skeleton 属性
| 属性名 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| animated | 是否使用动画 | boolean | false |
| count | 渲染多少个模板,建议保持较小数值 | number | 1 |
| loading | 是否显示骨架屏;为 false 时显示默认插槽内容 | boolean | false |
| rows | 骨架屏段落数量 | number | 3 |
| throttle | 渲染延迟,数字表示延迟显示;对象可配置 leading、trailing、initVal | number | object | 0 |
Skeleton 插槽
| 插槽名 | 说明 |
|---|---|
| default | 加载完成后真正渲染的 DOM |
| template | 渲染 skeleton 模板的内容 |
SkeletonItem API
SkeletonItem 属性
| 属性名 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| variant | 当前渲染的骨架类型 | p | text | h1 | h3 | caption | button | image | circle | rect | text |

