Ant Design Vue Skeleton 骨架屏组件完全指南:API 详解、组合子组件与源码原理
2026/9/20 18:08:17 网站建设 项目流程
  • 前端
  • UI组件
  • 设计系统

【免费下载链接】ant-design-vue

🌈 An enterprise-class UI components based on Ant Design and Vue. 🐜

项目地址:https://gitcode.com/gh_mirrors/an/ant-design-vue
点击查看免费下载

Skeleton 是 Ant Design Vue(ant-design-vue)提供的内容加载占位组件:当页面数据尚未就绪时,用灰色骨架块预先勾勒出标题、段落、头像、按钮、输入框等元素的轮廓,避免布局跳动、降低用户等待焦虑。本文以 components/skeleton/index.en-US.md 文档为主体,结合组件源码(Skeleton.tsxElement.tsxParagraph.tsx等)与官方示例(components/skeleton/demo/),完整讲解全部 API、组合用法、loading切换机制以及底层实现原理,读完即可在项目中落地一套高质量的骨架屏方案。

什么时候使用 Skeleton

官方文档给出了四条核心使用建议:

  • 资源需要长时间加载时:例如图表数据、详情接口返回前的等待阶段;
  • 组件包含大量信息时:典型的如 List 列表、Card 卡片,一次性渲染大量结构,骨架屏能有效缓解首屏白屏;
  • 仅在首次加载数据时生效:Skeleton 定位是"首次加载"占位,二次刷新建议复用已缓存的结构或直接展示内容;
  • 可被 Spin 替代,但体验更优:任何场景下都可用 Spin 加载态替代,但 Skeleton 通过勾勒真实内容轮廓(标题、段落、头像),让用户预知页面结构,感知上更流畅、更接近最终形态。

简单地说:Spin 表达"系统正在加载",Skeleton 表达"内容长这样、马上就好"

快速上手:基础用法与组合骨架

最简单的骨架屏只需要一行模板:

<template> <a-skeleton /> </template>

对应官方示例 components/skeleton/demo/basic.vue。默认渲染一个包含"标题 + 段落"的占位块。在 Skeleton.tsx 中可以看到默认值定义:

props: initDefaultProps(skeletonProps(), { avatar: false, title: true, paragraph: true, }),

即默认显示title(标题占位)和paragraph(段落占位),不显示avatar

更贴近真实场景的是复杂布局示例 components/skeleton/demo/complex.vue(组合头像 + 标题 + 段落)以及列表示例 components/skeleton/demo/list.vue。头像 + 标题 + 段落的组合会自动生成一套经过视觉优化的默认比例,这一逻辑由 Skeleton.tsx 中的三个辅助函数完成:

  • getAvatarBasicProps:当"有标题且无段落"时返回{ size: 'large', shape: 'square' }(方形大头像),否则返回{ size: 'large', shape: 'circle' }(圆形头像);
  • getTitleBasicProps:无头像有段落时标题宽度38%,有头像有段落时标题宽度50%
  • getParagraphBasicProps:默认行数 2 行,无头像或无标题时末行宽度61%,仅标题无头像时行数调整为 3 行。

也就是说,你只管声明"要哪些块",组件会自动编排出一套协调的骨架比例,无需手动逐个调宽度。

API 详解:Skeleton 核心属性

文档中 Skeleton 组件的完整属性表如下:

PropertyDescriptionTypeDefault
active显示动画效果(闪烁/呼吸渐变)booleanfalse
avatar显示头像占位boolean | SkeletonAvatarPropsfalse
loadingtrue时显示骨架boolean-
paragraph显示段落占位boolean | SkeletonParagraphPropstrue
title显示标题占位boolean | SkeletonTitlePropstrue

对应源码 skeletonProps(),注意源码中还有文档未列出的prefixClsround两个内部/扩展属性:

  • active:开启后骨架块呈现从左到右的流光扫过动画,用于提示"正在加载中";
  • avatar/title/paragraph既可传布尔值,也可传对象。传true/false控制是否渲染该块;传对象则进一步定制该块的形状、尺寸、宽度等细节(见下文三个子 Props 表);
  • loading:核心的"真实内容切换"开关。当loadingtrue时渲染骨架,为false时渲染插槽(default slot)中的真实内容。源码判断逻辑见 Skeleton.tsx:
if (loading || props.loading === undefined) { // ...渲染骨架占位 } return slots.default?.();

关键细节:当loading**未传值(undefined)**时,Skeleton 默认也渲染骨架——这与文档中 Default 列为-的行为一致,意味着该组件天然作为"默认占位"存在。只有显式传入loading={false}才会展示真实内容。

加载完成切换:loading 与子组件插槽

官方示例 components/skeleton/demo/children.vue 展示了最经典的使用模式:先用a-skeleton包裹真实内容,再通过loading布尔值控制切换:

<template> <a-space direction="vertical" style="width: 100%" :size="16"> <a-skeleton :loading="loading"> <div> <h4>Ant Design Vue, a design language</h4> <p>We supply a series of design principles, practical patterns and high quality design resources (Sketch and Axure), to help people create their product prototypes beautifully and efficiently.</p> </div> </a-skeleton> <a-button :disabled="loading" @click="showSkeleton">Show Skeleton</a-button> </a-space> </template> <script lang="ts" setup> import { ref } from 'vue'; const loading = ref<boolean>(false); const showSkeleton = () => { loading.value = true; setTimeout(() => { loading.value = false; }, 3000); }; </script>

这一段就是骨架屏在真实业务中的标准用法:数据请求发出时loading = true显示骨架,接口返回后loading = false切换为真实内容。由于骨架与真实内容处于同一布局位置,切换时页面结构几乎不变,不会产生"先空白、后跳动"的割裂感。对应源码正是上文slots.default?.()的插槽渲染逻辑。

子属性配置:头像、标题、段落

SkeletonAvatarProps(头像)

PropertyDescriptionTypeDefault
shape头像形状circle|square-
size头像尺寸number |large|small|default-

用法示例:

<a-skeleton :avatar="{ size: 'large', shape: 'square' }" />

源码见 Avatar.tsx:shape支持circle/squaresize除枚举值外还支持数字(此时按像素渲染宽高)。数值尺寸的最终落地在 Element.tsx:

const sizeStyle: CSSProperties = typeof size === 'number' ? { width: `${size}px`, height: `${size}px`, lineHeight: `${size}px` } : {};

SkeletonTitleProps(标题)

PropertyDescriptionTypeDefault
width标题宽度number | string-

Title.tsx 的实现非常精简:数字会被自动追加px单位,字符串(如'50%')直接作为 CSS width 使用:

const zWidth = typeof width === 'number' ? `${width}px` : width; return <h3 class={prefixCls} style={{ width: zWidth }} />;

SkeletonParagraphProps(段落)

PropertyDescriptionTypeDefault
rows段落行数number-
width段落宽度。传入数组时可为每一行单独设置宽度;否则只设置最后一行的宽度number | string | Array<number | string>-

这是 Skeleton 中最灵活的配置。源码 Paragraph.tsx 展示了它的"数组逐行 + 非数组仅末行"语义:

const getWidth = (index: number) => { const { width, rows = 2 } = props; if (Array.isArray(width)) { return width[index]; // 数组:逐行取对应宽度 } // 非数组:仅最后一行(rows - 1 === index)使用该宽度 if (rows - 1 === index) { return width; } return undefined; };

示例:

<a-skeleton :paragraph="{ rows: 4, width: ['40%', '80%', '60%', '90%'] }" /> <!-- 四行段落,每行宽度各不相同;省略数组时 width 只作用于最后一行 -->

组合子组件:Skeleton.Button / Input / Image / Avatar / Title(3.0+)

文档指出SkeletonButtonPropsSkeletonInputProps为 3.0+ 新增能力。除了主Skeleton组件外,ant-design-vue 还以静态属性的形式挂载了 5 个独立子组件(见 components/skeleton/index.tsx):Skeleton.ButtonSkeleton.AvatarSkeleton.InputSkeleton.ImageSkeleton.Title,全部通过Skeleton.install一并注册到应用中,模板中可直接使用a-skeleton-buttona-skeleton-avatara-skeleton-inputa-skeleton-image等标签。每个子组件的尺寸基准(large/small/default)与对应真实组件保持一致,保证"骨架形态 ≈ 真实形态"。

SkeletonButtonProps(骨架按钮)

PropertyDescriptionTypeDefault
active显示动画效果booleanfalse
block是否撑满父容器宽度booleanfalse
shape按钮形状circle|round|default-
size按钮尺寸large|small|default-

SkeletonInputProps(骨架输入框)

PropertyDescriptionTypeDefault
active显示动画效果booleanfalse
size输入框尺寸large|small|default-

SkeletonImage(骨架图片)

源码 Image.tsx 内置了一段 SVG 图片占位(viewBox="0 0 1098 1024"的山水图形路径),无需任何 props 即可渲染一个带图标轮廓的图片占位块,适用于商品图、封面图等场景。

官方示例 components/skeleton/demo/element.vue 综合演示了按钮、头像、输入框、图片的搭配,并附带了active(动画开关)、block(按钮撑满)、size(尺寸切换)、shape(形状切换)的交互控制面板,是理解这几个子组件最直观的参考。组件内部结构上,Button/Input/Avatar/Image均复用 Element.tsx 作为最终渲染单元——Element根据size追加-lg/-sm类、根据shape追加-circle/-square/-round类,数字尺寸直接以内联样式设置宽高。

源码级补充:RTL、主题样式与注册机制

  • RTL 支持:主组件在 Skeleton.tsx 中通过direction.value === 'rtl'追加-rtl类,配合useConfigInject自动感知 ConfigProvider 的方向配置,无需手动处理镜像布局;
  • 样式注入:组件通过useStyle(cssinjs 方案,见 components/skeleton/style/index.ts)在渲染时按需注入样式,并支持主题令牌(Design Token)定制与 hashId 作用域隔离,接入 ConfigProvider 的主题能力后骨架色可随全局主题联动;
  • 类型导出SkeletonButtonPropsSkeletonInputPropsSkeletonAvatarPropsSkeletonTitlePropsSkeletonProps等类型均从 components/skeleton/index.tsx 导出,便于在<script setup>中做强类型约束(示例 element.vue 中即通过SkeletonButtonProps['size']SkeletonAvatarProps['shape']约束 ref 类型)。

总结:Skeleton 最佳实践清单

  1. 首次加载用 Skeleton,刷新加载用 Spin:按官方建议,Skeleton 只适合首次数据加载,让用户提前感知页面结构;
  2. loading+ 默认插槽做无缝切换:把真实内容放进<a-skeleton :loading="loading">,数据返回后自动替换,避免布局跳动;
  3. 善用对象形式 propsavatar/title/paragraph传对象即可精确控制形状、尺寸、行数与逐行宽度,而不必自己拼 CSS;
  4. 页面级骨架用组合形态:头像 + 标题 + 段落会被自动编排出协调比例(标题 50%、段落 2 行、末行 61%),直接可用;
  5. 局部占位用子组件:按钮、输入框、图片等场景优先使用a-skeleton-buttona-skeleton-inputa-skeleton-image,形态与真实组件对齐;
  6. 开启active提升感知:需要明确表达"加载中"时给骨架加上流光动画,等待体验更好。

通过本文的 API 表格、官方示例与源码解析,你可以在 ant-design-vue 项目中快速实现从"全页骨架"到"局部元素占位"的完整加载体验。

  • 前端
  • UI组件
  • 设计系统

【免费下载链接】ant-design-vue

🌈 An enterprise-class UI components based on Ant Design and Vue. 🐜

项目地址:https://gitcode.com/gh_mirrors/an/ant-design-vue
点击查看免费下载

相关推荐

上一篇:MIT App Inventor终极指南:零代码开发Android/iOS应用的完整教程
下一篇:Leaf开发规范文档:Java编码风格与API设计最佳实践

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询