十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

ant-design-vue Skeleton 骨架屏组件完全指南:API 详解与源码级实现原理

ant-design-vue Skeleton 骨架屏组件完全指南:API 详解与源码级实现原理 ant-design-vue Skeleton 骨架屏组件完全指南API 详解与源码级实现原理【免费下载链接】ant-design-vue An enterprise-class UI components based on Ant Design and Vue. 项目地址: https://gitcode.com/gh_mirrors/an/ant-design-vueSkeleton骨架屏是 ant-design-vue 中用于「在内容加载完成前展示占位图形」的反馈型组件能显著缓解用户等待焦虑、降低页面跳动感。本文将围绕 components/skeleton/index.zh-CN.md 官方文档的完整 API 体系展开并结合仓库源码Skeleton.tsx、style/index.ts 等剖析其组合逻辑、默认布局策略、动画实现与样式 Token 机制帮助你在真实项目中正确选型、精准配置并理解其底层运作方式。一、组件定位什么时候该用 Skeleton根据官方文档Skeleton 的核心使用场景有四类网络较慢、需要长时间等待加载处理的场景避免页面长时间空白图文信息内容较多的列表 / 卡片用骨架占位勾勒出即将出现的内容轮廓仅在第一次加载数据时使用数据就绪后切换为真实内容它可以被 Spin 完全替代但在可用场景下能提供比 Spin 更好的视觉效果和用户体验——Spin 只是一个居中的加载图标而 Skeleton 通过模拟标题、段落、头像的真实排版结构让用户提前感知页面布局减少加载完成时的视觉跳动。从组件分类看Skeleton 属于「反馈Feedback」类型组件见文档 frontmatter 中的type: 反馈与 Spin、Message 等并列定位是「在需要等待加载内容的位置提供一个占位图形组合」。二、Skeleton 主组件 API 详解Skeleton 主组件接收 5 个核心属性官方文档参数表如下属性说明类型默认值active是否展示动画效果booleanfalseavatar是否显示头像占位图boolean | SkeletonAvatarPropsfalseloading为true时显示占位图。反之则直接展示子组件boolean-paragraph是否显示段落占位图boolean | SkeletonParagraphPropstruetitle是否显示标题占位图boolean | SkeletonTitlePropstrue2.1 基本用法与默认组合最简单的用法只需一行代码见 demo/basic.vuea-skeleton /不传任何参数时会渲染出「标题 段落」的默认骨架组合。这一行为由 Skeleton.tsx 中的initDefaultProps决定props: initDefaultProps(skeletonProps(), { avatar: false, title: true, paragraph: true, }),即默认avatarfalse、titletrue、paragraphtrue与文档默认值完全一致。2.2 avatar / title / paragraph布尔值还是对象这三个属性既可以是boolean也可以是各自对应的配置对象。当传入对象时其内部的配置项会合并到组件自动计算的基础属性之上。核心逻辑见 Skeleton.tsxfunction getComponentPropsT(prop: T | boolean | undefined): T | {} { if (prop typeof prop object) { return prop; } return {}; }getComponentProps负责抽取对象形式的配置当传入布尔值时返回空对象则完全采用组件内部的默认布局。2.3 智能默认布局根据组合自动推算占位尺寸Skeleton 并不是简单地堆砌三个占位块而是会根据「当前显示了哪些部分」自动调整每个部分的默认尺寸让组合看起来更接近真实排版。这套逻辑在 Skeleton.tsx 中实现function getAvatarBasicProps(hasTitle: boolean, hasParagraph: boolean): SkeletonAvatarProps { if (hasTitle !hasParagraph) { // 只有标题时头像用方形 return { size: large, shape: square }; } return { size: large, shape: circle }; } function getTitleBasicProps(hasAvatar: boolean, hasParagraph: boolean): SkeletonTitleProps { if (!hasAvatar hasParagraph) { return { width: 38% }; } if (hasAvatar hasParagraph) { return { width: 50% }; } return {}; } function getParagraphBasicProps(hasAvatar: boolean, hasTitle: boolean): SkeletonParagraphProps { const basicProps: SkeletonParagraphProps {}; if (!hasAvatar || !hasTitle) { basicProps.width 61%; } if (!hasAvatar hasTitle) { basicProps.rows 3; } else { basicProps.rows 2; } return basicProps; }可以总结出以下默认策略头像avatar默认size: large当「有标题但无段落」时自动变为square方形其余情况为circle圆形标题title有段落无头像时宽度为38%有头像且有段落时宽度为50%否则撑满 100%段落paragraph无头像或无标题时宽度为61%只作用于最后一行无头像但有标题时默认 3 行其余情况默认 2 行。因此像官方演示中的「复杂组合」——a-skeleton avatar :paragraph{ rows: 4 } /见 demo/complex.vue——只需覆盖paragraph.rows头像与标题的尺寸、宽度仍由组件自动推导。2.4 loading占位与真实内容的一键切换loading是 Skeleton 与数据流结合的关键开关。为true时渲染占位图为false时直接渲染slots.default中的真实内容。该分支逻辑见 Skeleton.tsxif (loading || props.loading undefined) { // ... 渲染骨架占位图 } return slots.default?.();注意一个细节props.loading undefined时同样渲染占位图即未显式传入 loading 时组件默认处于骨架态直到你传入loadingfalse才展示子组件。官方演示 demo/children.vue 给出了典型用法——加载中展示骨架加载完成后无缝切换为真实内容a-skeleton :loadingloading div h4Ant 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 :disabledloading clickshowSkeletonShow Skeleton/a-buttonconst loading refboolean(false); const showSkeleton () { loading.value true; setTimeout(() { loading.value false; }, 3000); };结合a-list使用时的完整示例可参考 demo/list.vue在a-list-item内部包裹a-skeleton :loadingloading active avatar实现列表骨架加载。2.5 active加载光效动画active为true时骨架块会呈现从左到右的渐变扫光动画。该动画并非独立的 JS 逻辑而是纯 CSS 实现由 style/index.ts 定义的Keyframes驱动const skeletonClsLoading new Keyframes(ant-skeleton-loading, { 0%: { transform: translateX(-37.5%) }, 100%: { transform: translateX(37.5%) }, });动画时长、渐变色带等由设计 Token 控制style/index.tsskeletonLoadingBackground: linear-gradient(90deg, ${token.color} 25%, ${token.colorGradientEnd} 37%, ${token.color} 63%), skeletonLoadingMotionDuration: 1.4s,即背景是一条 90 度方向的渐变基础色 25% → 渐变末端色 37% → 基础色 63%通过::after伪元素在 1.4 秒内往返平移形成扫光效果style/index.ts。官方演示见 demo/active.vuea-skeleton active /。三、组合子组件SkeletonAvatar / SkeletonTitle / SkeletonParagraph主组件内部将「头像 / 标题 / 段落」拆分为三个独立组件位于 components/skeleton/ 目录下Avatar.tsx渲染头像占位接收size与shapeTitle.tsx渲染标题占位接收widthParagraph.tsx渲染段落占位接收rows与width。3.1 SkeletonAvatarProps属性说明类型默认值shape指定头像的形状circle|square-size设置头像占位图的大小number |large|small|default-从源码看Avatar.tsx 内部对未传值的情况做了兜底size默认default、shape默认circle。size传入数字时会被转换为像素尺寸作用于宽高逻辑见 Element.tsxconst sizeStyle: CSSProperties typeof size number ? { width: ${size}px, height: ${size}px, lineHeight: ${size}px, } : {};3.2 SkeletonTitleProps属性说明类型默认值width设置标题占位图的宽度number | string-Title.tsx 的实现非常简洁数字宽度会被拼接为px单位字符串则原样作为 CSS 宽度const zWidth typeof width number ? ${width}px : width; return h3 class{prefixCls} style{{ width: zWidth }} /;因此width既可以是100渲染为100px也可以是50%这类百分比字符串。3.3 SkeletonParagraphProps属性说明类型默认值rows设置段落占位图的行数number-width设置段落占位图的宽度若为数组时则为对应的每行宽度反之则是最后一行的宽度number | string | Arraynumber | string-width的两种形态对应两种语义见 Paragraph.tsxconst getWidth (index: number) { const { width, rows 2 } props; if (Array.isArray(width)) { return width[index]; // 数组逐行指定宽度 } // 非数组仅作用于最后一行 if (rows - 1 index) { return width; } return undefined; };传入数组如[40%, 60%, 80%]数组下标与行号一一对应每一行使用对应宽度传入单个值number 或 string只作用于最后一行其余行撑满容器宽度。注意rows默认值为 2源码const { width, rows 2 } props与前面主组件默认段落行数策略一致。四、独立占位元素SkeletonButton / SkeletonInput / SkeletonImage3.0从 3.0 版本起Skeleton 还提供了三种可直接独立使用的占位元素可通过Skeleton.Button、Skeleton.Input、Skeleton.Image或全局注册后的a-skeleton-button等标签使用注册逻辑见 index.tsx。4.1 SkeletonButtonProps3.0属性说明类型默认值版本active是否展示动画效果booleanfalseblock将按钮宽度调整为其父宽度的选项booleanfalseshape指定按钮的形状circle|round|default-size设置按钮的大小large|small|default-Button.tsx 内部将size默认值设为default。block为true时按钮占位宽度扩展为父容器 100%对应样式见 style/index.ts 中-block规则。4.2 SkeletonInputProps3.0属性说明类型默认值active是否展示动画效果booleanfalsesize设置输入框的大小large|small|default-Input.tsx 通过omit(skeletonElementProps(), [shape])剔除了输入框不适用的shape属性同时支持block源码类型定义SkeletonInputProps中包含block?: booleandemo 中也演示了a-skeleton-input stylewidth: 200px /这种覆盖宽度写法。4.3 SkeletonImage3.0虽然官方 API 表未单独列出但 Image.tsx 提供了图片占位渲染一个内嵌的 SVG 图片图标viewBox0 0 1098 1024SkeletonImageProps剔除了size、shape、active三个属性。官方演示 demo/element.vue 中展示了按钮、头像、输入框、图像的完整组合及 Active / Block / Size / Shape 的联动控制。4.4 尺寸与形状的底层统一处理所有占位元素最终都收敛到 Element.tsx 这个函数式组件。它统一处理三类维度尺寸large/small映射为-lg/-sm类名数字映射为内联像素宽高形状circle/square/round映射为对应形状类名颜色与圆角由 style/index.ts 中的genSkeletonElementButton等规则控制尺寸分别对应设计 Token 的controlHeight/controlHeightLG/controlHeightSM即 default / large / small 三档按钮宽度为controlHeight * 2、输入框宽度为controlHeight * 5。五、样式定制Token 与 ConfigProvider 联动Skeleton 的样式通过 style/index.ts 中的genComponentStyleHook(Skeleton, ...)接入 ant-design-vue 的主题系统。它对外暴露两个ComponentTokenstyle/index.tsexport type ComponentToken { color: string; // 骨架块的基础填充色 colorGradientEnd: string; // 动画渐变末端色 };其默认值由主题 Token 映射而来style/index.tstoken { const { colorFillContent, colorFill } token; return { color: colorFillContent, colorGradientEnd: colorFill, }; }即基础色使用colorFillContent、渐变末端色使用colorFill这两个 Token 会随主题明暗模式自动切换。因此你可以通过全局主题配置覆盖Skeleton的color与colorGradientEnd来定制骨架颜色。此外Skeleton 内部还通过useConfigInject(skeleton, props)见 Skeleton.tsx接入 ConfigProvider继承prefixCls与direction支持全局组件前缀修改与 RTL 布局-rtl类名见 Skeleton.tsx。同时round属性可将标题、段落圆角切换为胶囊形状borderRadius: 100见 style/index.ts。六、与 Spin 的选型对比官方文档明确指出「可以被 Spin 完全代替但是在可用的场景下可以比 Spin 提供更好的视觉效果和用户体验」。实际选型建议内容区域为整块加载、无需预先呈现布局轮廓时使用Spin即可列表、卡片、详情页等有固定排版结构的区域优先使用Skeleton它按真实布局渲染占位内容加载完成切换时页面不会大幅跳动两者也可以组合使用在骨架区域内的操作按钮上叠加Spin兼顾「布局预告」与「局部加载反馈」。七、快速上手总结需求推荐写法最简单占位标题 段落a-skeleton /带扫光动画a-skeleton active /头像 多行段落a-skeleton avatar :paragraph{ rows: 4 } /见 demo/complex.vue数据加载切换a-skeleton :loadingloading真实内容/a-skeleton见 demo/children.vue列表骨架a-skeleton :loadingloading active avatar包裹a-list-item见 demo/list.vue按钮 / 输入框占位a-skeleton-button :activeactive /、a-skeleton-input :sizesize /见 demo/element.vue掌握以上 API 与底层实现后你可以在 ant-design-vue 项目中精准选用 Skeleton 的各类组合与独立元素并通过 Token 定制与 ConfigProvider 联动让骨架屏与你的设计系统保持一致。如需进一步研究源码可重点阅读 Skeleton.tsx组合与默认布局策略、Element.tsx尺寸/形状统一处理与 style/index.tsToken 与动画实现。【免费下载链接】ant-design-vue An enterprise-class UI components based on Ant Design and Vue. 项目地址: https://gitcode.com/gh_mirrors/an/ant-design-vue创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表