概述
Avatar:占位头像,默认为圆形,默认尺寸:Avatar medium:width: 48px,height: 48px。支持size、shape属性,取值见 API 参考。Image:占位图像,默认尺寸:width: 100%,height: 100%。Title:占位标题,默认尺寸:width: 100%,height: 24px。Paragraph:占位内容部分,默认尺寸:width: 100%,height: 16px,margin-bottom: 10px。Button:占位按钮,默认尺寸:width: 115px,height: 32px。
注意:默认样式均可通过
class或style进行自定义。
代码演示
如何引入
<script setup lang="ts">
import { Skeleton } from '@fibrous/semi-ui-vue';
</script>
基本使用
显示加载内容
代码
<script setup lang="ts">
import { ref } from 'vue';
import { Avatar, Button, Skeleton, Switch } from '@fibrous/semi-ui-vue';
const loading = ref(true);
</script>
<template>
<span :style="{ display: 'flex', alignItems: 'center' }">
<Switch aria-labelledby="skeleton-basic-toggle" @change="loading = !loading" />
<span id="skeleton-basic-toggle" :style="{ marginLeft: '10px' }">显示加载内容</span>
</span>
<br />
<Skeleton :loading="loading">
<template #placeholder>
<Skeleton.Avatar />
</template>
<Avatar color="blue" :style="{ marginBottom: '10px' }">U</Avatar>
</Skeleton>
<br />
<Skeleton :loading="loading" :style="{ width: '200px', height: '150px' }">
<template #placeholder>
<Skeleton.Image />
</template>
<img alt="avatar" height="150" src="/assets/placeholder/avatar-a.svg" />
</Skeleton>
<br />
<Skeleton :loading="loading" :style="{ width: '80px' }">
<template #placeholder>
<Skeleton.Title :style="{ marginBottom: '10px' }" />
</template>
<h4 :style="{ marginBottom: 0 }">Semi UI</h4>
</Skeleton>
<Skeleton :loading="loading" :style="{ width: '240px' }">
<template #placeholder>
<Skeleton.Paragraph :rows="2" />
</template>
<p :style="{ width: '240px' }">精心打磨每一个组件的用户体验,从用户的角度考虑每个组件的使用场景。</p>
</Skeleton>
<br />
<Skeleton :loading="loading">
<template #placeholder>
<Skeleton.Button />
</template>
<Button>Button</Button>
</Skeleton>
</template>组合使用
图片和标题。
代码
<script setup lang="ts">
import { Skeleton } from '@fibrous/semi-ui-vue';
</script>
<template>
<Skeleton loading>
<template #placeholder>
<div>
<Skeleton.Image :style="{ width: '200px', height: '150px' }" />
<Skeleton.Title :style="{ width: '120px', marginTop: '10px' }" />
</div>
</template>
<img alt="avatar" height="150" src="/assets/placeholder/avatar-a.svg" />
<h4>Semi UI</h4>
</Skeleton>
</template>统计数字。
代码
<script setup lang="ts">
import { Descriptions, Skeleton } from '@fibrous/semi-ui-vue';
const data = [{ key: '实际用户数量', value: '1,480,000' }];
</script>
<template>
<Skeleton loading>
<template #placeholder>
<div>
<Skeleton.Paragraph :rows="1" :style="{ width: '80px', marginBottom: '10px' }" />
<Skeleton.Title :style="{ width: '120px' }" />
</div>
</template>
<Descriptions :data="data" row />
</Skeleton>
</template>头像和标题。
代码
<script setup lang="ts">
import { Avatar, Skeleton } from '@fibrous/semi-ui-vue';
</script>
<template>
<Skeleton loading>
<template #placeholder>
<div :style="{ display: 'flex', alignItems: 'center' }">
<Skeleton.Avatar :style="{ marginRight: '12px' }" />
<Skeleton.Title :style="{ width: '120px' }" />
</div>
</template>
<Avatar color="blue" :style="{ marginRight: '12px' }">UI</Avatar>
<span>Semi UI</span>
</Skeleton>
</template>居中段落和按钮。
代码
<script setup lang="ts">
import type { StyleValue } from 'vue';
import { Button, Skeleton } from '@fibrous/semi-ui-vue';
const style: StyleValue = {
display: 'flex',
flexDirection: 'column',
alignItems: 'center',
width: '300px',
marginBottom: '10px',
};
</script>
<template>
<Skeleton loading :style="{ textAlign: 'center' }">
<template #placeholder>
<div :style="style">
<Skeleton.Paragraph :rows="3" :style="style" />
<Skeleton.Button />
</div>
</template>
<div :style="{ textAlign: 'center' }">
<p>Hi, Bytedance dance dance.</p>
<p>Hi, Bytedance dance dance.</p>
<Button>Button</Button>
</div>
</Skeleton>
</template>头像、标题和段落。
代码
<script setup lang="ts">
import { Avatar, Skeleton } from '@fibrous/semi-ui-vue';
const style = {
display: 'flex',
alignItems: 'flex-start',
};
</script>
<template>
<Skeleton loading>
<template #placeholder>
<div :style="style">
<Skeleton.Avatar :style="{ marginRight: '12px' }" />
<div>
<Skeleton.Title :style="{ width: '120px', marginBottom: '12px', marginTop: '12px' }" />
<Skeleton.Paragraph :rows="3" :style="{ width: '240px' }" />
</div>
</div>
</template>
<div :style="style">
<Avatar color="blue" :style="{ marginRight: '12px' }">UI</Avatar>
<div>
<h3>Semi UI</h3>
<p>Hi, Bytedance dance dance.</p>
<p>Hi, Bytedance dance dance.</p>
<p>Hi, Bytedance dance dance.</p>
</div>
</div>
</Skeleton>
</template>表格。
代码
<script setup lang="ts">
import { Skeleton, Table, type ColumnProps } from '@fibrous/semi-ui-vue';
const columns: ColumnProps[] = [
{
title: 'Name',
dataIndex: 'name',
},
{
title: 'Age',
dataIndex: 'age',
},
{
title: 'Address',
dataIndex: 'address',
},
];
const dataSource = [
{
key: '1',
name: 'John Brown',
age: 32,
address: 'New York No. 1 Lake Park, New York No. 1 Lake Park',
},
{
key: '2',
name: 'Jim Green',
age: 42,
address: 'London No. 1 Lake Park',
},
{
key: '3',
name: 'Joe Black',
age: 32,
address: 'Sidney No. 1 Lake Park',
},
{
key: '4',
name: 'Disabled User',
age: 99,
address: 'Sidney No. 1 Lake Park',
},
];
const placeholderColumns: ColumnProps[] = [1, 2, 3].map((key) => ({ dataIndex: `${key}` }));
const placeholderDataSource = [1, 2, 3, 4].map((key) => ({ key }));
</script>
<template>
<Skeleton loading>
<template #placeholder>
<div :style="{ position: 'relative' }">
<Table :columns="placeholderColumns" :dataSource="placeholderDataSource" :pagination="false" :style="{ backgroundColor: 'var(--semi-color-bg-1)' }">
<template #headerCell>
<Skeleton.Title :style="{ width: '0' }" />
</template>
<template #cell="{ column }">
<Skeleton.Paragraph :rows="1" :style="{ width: `${50 * Number(column.dataIndex)}px` }" />
</template>
</Table>
<div :style="{ position: 'absolute', left: 0, right: 0, top: 0, bottom: 0 }" />
</div>
</template>
<div>
<Table :columns="columns" :dataSource="dataSource" :pagination="false" />
</div>
</Skeleton>
</template>加载动画
通过设置 active 属性可以展示动画效果。
代码
<script setup lang="ts">
import { Avatar, Skeleton } from '@fibrous/semi-ui-vue';
const style = {
display: 'flex',
alignItems: 'flex-start',
};
</script>
<template>
<Skeleton active loading>
<template #placeholder>
<div :style="style">
<Skeleton.Avatar :style="{ marginRight: '12px' }" />
<div>
<Skeleton.Title :style="{ width: '120px', marginBottom: '12px', marginTop: '12px' }" />
<Skeleton.Paragraph :rows="3" :style="{ width: '240px' }" />
</div>
</div>
</template>
<div :style="style">
<Avatar color="blue" :style="{ marginRight: '12px' }">UI</Avatar>
<div>
<h3>Semi UI</h3>
<p>Hi, Bytedance dance dance.</p>
<p>Hi, Bytedance dance dance.</p>
<p>Hi, Bytedance dance dance.</p>
</div>
</div>
</Skeleton>
</template>API 参考
Skeleton
Props
| 属性 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| active | 是否展示动画效果。 | boolean | semiGlobalDefault("Skeleton", "active") |
| loading | 为 true 时显示 placeholder 插槽,反之显示默认插槽。 | boolean | semiDefault("Skeleton", "loading", true) |
Events
| 事件 | 说明 | 回调参数 |
|---|---|---|
| 无 |
Slots
| 插槽 | 说明 | 作用域参数 |
|---|---|---|
| default | 加载结束后显示的内容。 | any |
| placeholder | 加载等待时的占位元素。 | any |
Exposes
| 名称 | 说明 | 类型 |
|---|---|---|
| 无 |
class、style 与原生属性经 attrs 落在占位根元素上。loading 为 false 时组件只渲染默认插槽,不再有根元素,attrs 随占位一起丢弃。根元素的 aria-busy="true" 不能被 attrs 关闭。
Skeleton.Avatar
Props
| 属性 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| size | 占位头像的大小。 | Type"medium" | "small" | "extra-extra-small" | "extra-small" | "large" | "extra-large" | "medium" |
| shape | 占位头像的形状,可选 circle 或 square。 | "circle" | "square" | "circle" |
| prefixCls | 类名前缀,默认为 semi-skeleton。 | string | undefined |
| type | 替换占位块自带的类型,同时决定它的类名;不为 avatar 时 size、shape 不生效。 | string | undefined |
Events
| 事件 | 说明 | 回调参数 |
|---|---|---|
| 无 |
Slots
| 插槽 | 说明 | 作用域参数 |
|---|---|---|
| 无 |
Exposes
| 名称 | 说明 | 类型 |
|---|---|---|
| 无 |
class、style 与原生属性经 attrs 落在占位块上。
Skeleton.Image
Props
| 属性 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| prefixCls | 类名前缀,默认为 semi-skeleton。 | string | undefined |
| type | 替换占位块自带的类型,同时决定它的类名。 | string | undefined |
Events
| 事件 | 说明 | 回调参数 |
|---|---|---|
| 无 |
Slots
| 插槽 | 说明 | 作用域参数 |
|---|---|---|
| 无 |
Exposes
| 名称 | 说明 | 类型 |
|---|---|---|
| 无 |
Skeleton.Title
Props
| 属性 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| prefixCls | 类名前缀,默认为 semi-skeleton。 | string | undefined |
| type | 替换占位块自带的类型,同时决定它的类名。 | string | undefined |
Events
| 事件 | 说明 | 回调参数 |
|---|---|---|
| 无 |
Slots
| 插槽 | 说明 | 作用域参数 |
|---|---|---|
| 无 |
Exposes
| 名称 | 说明 | 类型 |
|---|---|---|
| 无 |
Skeleton.Button
Props
| 属性 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| prefixCls | 类名前缀,默认为 semi-skeleton。 | string | undefined |
| type | 替换占位块自带的类型,同时决定它的类名。 | string | undefined |
Events
| 事件 | 说明 | 回调参数 |
|---|---|---|
| 无 |
Slots
| 插槽 | 说明 | 作用域参数 |
|---|---|---|
| 无 |
Exposes
| 名称 | 说明 | 类型 |
|---|---|---|
| 无 |
Skeleton.Image、Skeleton.Title、Skeleton.Button 没有 size、shape,class、style 与原生属性经 attrs 落在占位块上。
Skeleton.Paragraph
Props
| 属性 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| prefixCls | 类名前缀,默认为 semi-skeleton。 | string | cssClasses.PREFIX |
| rows | 占位段落的行数。 | number | 4 |
Events
| 事件 | 说明 | 回调参数 |
|---|---|---|
| 无 |
Slots
| 插槽 | 说明 | 作用域参数 |
|---|---|---|
| 无 |
Exposes
| 名称 | 说明 | 类型 |
|---|---|---|
| 无 |
class、style 与原生属性经 attrs 落在 ul 根元素上。
Accessibility
- 加载时 Skeleton 的外层带有
aria-busy="true",占位块与段落占位带有aria-hidden="true",读屏只知道内容正在加载;使用方传入的同名属性优先于占位块上的aria-hidden,aria-busy不能被关闭。 - 加载结束后直接渲染子内容,不再有 Skeleton 的外层元素。
文案规范
- 不变的固定内容直接展示固定内容,可变的内容使用骨架屏展示
设计变量
下表是组件内部的 Sass 变量,不能覆写。定制样式请覆写 --semi-* CSS 变量(见 Design Token 页),或写不分层的 CSS 规则。
| Sass 变量 | 值 | 用法 |
|---|---|---|
| $animation_duration-skeleton-highlight | 1400ms | 骨架屏高亮动画时长 |
| $animation_function-skeleton-highlight | ease | |
| $color-skeleton_default-bg-default | var(--semi-color-fill-0) | 骨架屏背景色 - 默认 |
| $color-skeleton_loading-gradient-bg-active | var(--semi-color-fill-1) | 骨架屏背景色 - 动画开启后 |
| $width-skeleton_avatar_extra_extra_small | 20px | 头像骨架屏尺寸 - 极小 |
| $width-skeleton_avatar_extra_small | 24px | 头像骨架屏尺寸 - 超小 |
| $width-skeleton_avatar_small | 32px | 头像骨架屏尺寸 - 小 |
| $width-skeleton_avatar_medium | 48px | 头像骨架屏尺寸 - 中 |
| $width-skeleton_avatar_large | 72px | 头像骨架屏尺寸 - 大 |
| $width-skeleton_avatar_extra_large | 128px | 头像骨架屏尺寸 - 超大 |
| $width-skeleton_button | 115px | 按钮骨架屏宽度 |
| $height-skeleton_li | 16px | 段落骨架屏高度 |
| $height-skeleton_title | $height-control-small | 标题骨架屏高度 |
| $height-skeleton_button | $height-control-default | 按钮骨架屏高度 |
| $spacing-skeleton_li-marginBottom | 10px | 按钮骨架屏高度 |
| $radius-skeleton_item | var(--semi-border-radius-small) | 骨架屏圆角 |
| $radius-skeleton_li | var(--semi-border-radius-small) | 骨架屏圆角 |