Skeleton 骨架屏
import { Skeleton } from '@apollo-design/ui';按预期结构显示加载占位。loading由调用者控制;组件不发请求,也不自动完成加载。
代码演示
基础 #
不传任何 props 时的默认形态:avatar 为 false、title 与 paragraph 均为 true。
所以只有 -section、没有 -header,段落默认 3 行。
带头像 #
avatar 为真时多出一个 -header 容器(与 -section 并列,不是嵌套)。
⚠️ 头像的形状由另外两项推导:hasTitle && !hasParagraph 时是方形,
否则是圆形;size 恒为 large。本示例关掉了段落,所以是方形。
加载完成前显示骨架 #
loading 是三态:未传与 true 都显示骨架,只有 false 显示子内容。
由调用者维护loading状态;业务正文切换时会卸载,需持久的输入数据放在父级响应状态中。
动画与圆角 #
active 让灰块有呼吸动画;round 把标题与段落的圆角拉到「胶囊」级别
(-round 是根元素上的类名,作用于后代的标题/段落)。
语义化样式 #
classNames / styles 各支持 6 个键,与 DOM 结构一一对应:
root / header / section / avatar / title / paragraph。
主组件同时支持对象与函数,函数读取当前{ props };原生class/style作用于根,区块配置的class/style与对应语义配置合并。
当前组件主题 #
六种骨架形态共享当前源主题。切换主题、动画或原生标题高度变量,输入值与焦点保持;内容样式使用styles.content,普通style作用于根。
All six shapes follow the current source theme. Theme and native-variable changes preserve the editor; styles.content targets the inner content and native style targets the root.
包含子内容 #
loading 为 true 时显示骨架,为 false 时只渲染默认插槽;点击按钮模拟一次加载。
复杂组合 #
Skeleton.Node 承载自定义占位内容,与带 avatar / paragraph 的 Skeleton 组合成卡片骨架;按钮切换 active。
骨架元素 #
Skeleton.Avatar / Skeleton.Button / Skeleton.Input / Skeleton.Image 可独立组合,按钮统一切换 active 微光动画。
原八个示例保留,并新增可切换主题与原生变量的示例。查看加载开关、独立元素、完整内容和当前组件Token。
<script setup lang="ts">
import { ref } from 'vue';
import { Skeleton } from '@apollo-design/ui';
const loading = ref(true);
const draft = ref('保留业务数据');
</script>
<template>
<button type="button" @click="loading = !loading">切换加载</button>
<Skeleton :loading="loading" avatar>
<input v-model="draft" aria-label="业务输入" />
</Skeleton>
</template>
API
Skeleton Props
| 属性 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| active | 微光动画,遵守减少动画与源motion:false | boolean | false |
| loading | 只有false显示真实内容;未传/undefined均显示骨架 | boolean | — |
| prefixCls | 当前类名前缀 | string | apollo-skeleton |
| avatar | 头像块及单元素配置 | boolean / SkeletonAvatarProps | false |
| title | 标题块配置 | boolean / SkeletonTitleProps | true |
| paragraph | 段落块配置 | boolean / SkeletonParagraphProps | true |
| round | 标题与段落使用胶囊圆角 | boolean | false |
| classNames | 六语义落点的类;函数读取当前{ props } |
SkeletonSemanticValue<SkeletonSemanticClassNames> | — |
| styles | 六语义落点的样式;函数读取当前{ props } |
SkeletonSemanticValue<SkeletonSemanticStyles> | — |
独立子组件 Props
具名SkeletonAvatar/SkeletonButton/SkeletonInput/SkeletonImage/SkeletonNode与静态Skeleton.Avatar/Button/Input/Image/Node指向同一组件。
| 属性 | 适用 | 说明 |
|---|---|---|
| prefixCls | 全部 | 当前前缀 |
| active | 全部 | 微光动画,默认false |
| classNames / styles | 全部 | 对象形式,root为外层div,content为内层占位/内容 |
| size | Avatar | small / medium / middle / large / 既有default别名 / 非负有限像素数;默认取Provider componentSize |
| shape | Avatar | circle(默认)/ square |
| size | Button / Input | small / medium / middle / large / 既有default别名;默认取Provider componentSize |
| shape | Button | circle / square / round / default;缺省不加形状类 |
| block | Button / Input | 撑满一行,默认false |
| internalClassName | Node | 已有内容类覆盖;空值使用默认node类,Image内部用它选择image类 |
size="default"仍保留既有废弃告警,使用medium。根className别名已移除;内层尺寸/样式使用styles.content。
块配置
avatar/title/paragraph配置中的prefixCls/className/style是数据字段,保留并与对应语义合并;语义样式最后覆盖配置style,类拼接。
| 字段 | 适用 | 说明 |
|---|---|---|
| size / shape | avatar | 尺寸与circle/square;默认large,存在title且无paragraph时为square,否则circle |
| width | title | 数字像素或CSS字符串;无头像且有段落时38%,两者都有时50%,否则不设 |
| rows | paragraph | 默认无头像且有title时3,否则2;非有限/负值为空,有限正小数截断 |
| width | paragraph | 数组逐行,单值只作用最后一行;无头像或无title时默认末行61% |
非有限数值长度忽略,0保留。avatar是单个占位元素,使用主classNames.avatar/styles.avatar,不接受独立双层组件的classNames/styles配置。
原生 attrs、Provider与优先级
六组件的id/data/ARIA/tabindex/原生事件均落真实根。Vue字符串、数组、对象class/style有效;原生样式最后覆盖,子组件content使用独立语义落点。主loading=false没有根,attrs不会复制到业务槽;需要持久宿主时自行包裹。
主组件读取当前components.skeleton的className/style/classNames/styles,配置替换、删除和恢复即时生效。五个子组件消费全局前缀、适用尺寸和源主题;主六槽配置不套入子组件两槽。最近Provider与实例隔离,RTL即时更新。任意自定义前缀仍需对应静态CSS。
Slots / Emits / v-model
| 组件 / 槽 | 说明 |
|---|---|
| Skeleton default | loading=false时直接渲染完整真实内容,无包裹 |
| SkeletonNode default | 当前完整自定义内容,原生编辑器不会因周边样式/主题改变重挂 |
| SkeletonImage default | 有槽时优先,含有意空槽;无槽显示原内置SVG |
无业务emits或v-model,loading受控。原生监听收到DOM事件。主六语义落点为root/header/section/avatar/title/paragraph;子组件为root/content。
Expose
仅主Skeleton公开nativeElement: HTMLDivElement | null。loading=false或卸载后为null。正文loading开关时会卸载,数据应保存在调用者响应状态中;不承诺卸载后的节点或焦点身份。
组件Token
全部形态读取当前theme.components.Skeleton,移除/恢复响应;现代渐变字段优先既有别名,再回退当前Alias。对应--apollo-skeleton-*变量可在根原生style覆盖。
| Token | 类型 | 默认来源 |
|---|---|---|
| gradientFromColor | string | colorFillContent |
| gradientToColor | string | colorFill |
| color(既有deprecated别名) | string | gradientFromColor |
| colorGradientEnd(既有deprecated别名) | string | gradientToColor |
| titleHeight | number / CSS长度string | controlHeight / 2 |
| blockRadius | number | borderRadiusSM |
| paragraphMarginTop | number | marginLG + marginXXS |
| paragraphLiHeight | number | controlHeight / 2 |
无障碍、SSR与样式
加载根为aria-busy=true,header/section装饰内容aria-hidden,空占位标题不进入可访问树;可通过原生attrs提供role/名称。Node/Image真实槽内容保持可访问,内置SVG为装饰图。active遵守prefers-reduced-motion与源motion:false,不自动加live播报。
SSR不依赖window;默认槽和当前主题在服务端可渲染,水合与生产浏览器验收状态以完整清单为准。样式入口:@apollo-design/ui/skeleton/style.css。破坏性变更和旧/新写法见仓库docs/migrations/skeleton-contracts.md;本轮实际命令、证据与未验边界见docs/audit/2026-10-27-skeleton-contract-audit.md。