ant-design Badge 徽标数组件完全指南:API 详解、源码原理与实战应用
2026/9/18 10:20:55 网站建设 项目流程

ant-design Badge 徽标数组件完全指南:API 详解、源码原理与实战应用

【免费下载链接】ant-designAn enterprise-class UI design language and React UI library项目地址: https://gitcode.com/gh_mirrors/ant/ant-design

Badge(徽标数)是 ant-design 数据展示组件家族中最常用的组件之一,通常出现在通知图标或头像的右上角,用于展示待处理消息条数、未读标记或状态信号。本文基于当前仓库 components/badge 目录下的官方中文文档与源码实现,系统讲解 Badge 的全部 API、核心交互行为(封顶、溢出、滚动动画、状态点、缎带等)及其底层实现原理,帮助你在实际项目中熟练使用并知其所以然。

何时使用

一般出现在通知图标或头像的右上角,用于显示需要处理的消息条数,通过醒目视觉形式吸引用户处理。典型场景包括:

  • 导航栏/侧边栏的通知入口,展示未读消息数量;
  • 头像右上角展示待办数量或在线状态;
  • 列表项右侧展示待处理事项的数量标记;
  • 卡片或内容区域用状态点(success/error/warning)表达业务状态。

快速上手

Badge 作为独立组件从antd包中导出,最简单的用法是包裹一个子元素并传入count

import { Badge, Avatar } from 'antd'; const App: React.FC = () => ( <Badge count={5}> <Avatar shape="square" size="large" /> </Badge> );

完整可运行示例可参考仓库中的 基本用法演示,其中还演示了count={0} showZero强制展示零值,以及把count直接传一个 ReactNode(如<ClockCircleOutlined />)实现自定义图标徽标的能力。

Badge API

通用属性参考:通用属性。Badge 组件对外暴露的核心属性如下表:

参数说明类型默认值版本
color自定义小圆点的颜色string-
count展示的数字,大于 overflowCount 时显示为${overflowCount}+,为 0 时隐藏ReactNode-
classNames语义化结构 classRecord<SemanticDOM, string>-5.7.0
dot不展示数字,只有一个小红点booleanfalse
offset设置状态点的位置偏移[number, number]-
overflowCount展示封顶的数字值number99
showZero当数值为 0 时,是否展示 Badgebooleanfalse
size在设置了count的前提下有效,设置小圆点的大小default|small--
status设置 Badge 为状态点success|processing|default|error|warning-
styles语义化结构 styleRecord<SemanticDOM, CSSProperties>-5.7.0
text在设置了status的前提下有效,设置状态点的文本ReactNode-
title设置鼠标放在状态点上时显示的文字string-

核心属性详解

count(展示的数字):默认值为null(源码中count = null,见 index.tsx)。计数逻辑遵循三条规则:

  1. 大于overflowCount时显示为${overflowCount}+
  2. 为 0 时隐藏(除非设置showZero);
  3. 传入ReactNode时直接渲染自定义内容,例如 basic.tsx 中传入<ClockCircleOutlined style={{ color: '#f5222d' }} />

从源码看(index.tsx),展示值由numberedDisplayCount计算:count > overflowCount ? \${overflowCount}+` : count,随后isZeroignoreCountisHidden等布尔量共同决定徽标是否渲染。特别地,负数和字符串数字(如-10"-10""3.5"`)也能正确展示,测试用例见 index.test.tsx 与 index.test.tsx。

overflowCount(封顶数字值):默认99,当 count 超过该值时显示${overflowCount}+。参考 封顶数字演示:

<Badge count={99} /> <Badge count={100} /> {/* 显示 99+ */} <Badge count={99} overflowCount={10} /> {/* 显示 10+ */} <Badge count={1000} overflowCount={999} /> {/* 显示 999+ */}

dot(小红点):设置为true时不展示数字,只显示一个小红点。参考 讨嫌的小红点演示。注意两个边界行为(源码与测试均已覆盖):dotcount为 0 时不展示(showAsDot = dot && !isZero,见 index.tsx),且 dot 模式下不会因为位数多而加宽为“多字符胶囊”样式,测试见 index.test.tsx。

showZero(是否展示零值):默认false,即count={0}时徽标整体隐藏。设置为true后可展示数字 0,参考 basic.tsx 中的<Badge count={0} showZero>

size(徽标大小):在设置了count的前提下有效,取值defaultsmall。参考 大小演示。源码中size === 'small'会额外追加${prefixCls}-count-sm样式类(index.tsx),其视觉差异由样式文件定义(见下文主题变量部分)。

offset(位置偏移):类型为[number, number],分别表示水平与垂直偏移。参考 自定义位置偏移演示:

<Badge count={5} offset={[10, 10]}> <Avatar shape="square" size="large" /> </Badge>

源码中偏移的实现值得注意(index.tsx):垂直方向通过marginTop: offset[1]实现;水平方向根据ConfigContext中的direction判断——LTR 下设置right = -parseInt(offset[0]),RTL 下设置left = parseInt(offset[0]),从而天然适配从右到左的阅读方向。offset同样支持传入 ReactNode 作为 count 的场景(index.test.tsx)。

status(状态点):取值success|processing|default|error|warning,参考 状态点演示:

<Badge status="success" /> <Badge status="processing" /> <Badge status="error" text="Error" />

状态点可搭配text展示文字(如text="Error"),也可单独使用。源码中hasStatus判定(index.tsx)说明:只有当statuscolor被设置、且count为空(ignoreCount)时,组件才会以“状态点”模式渲染(即根节点只渲染状态圆点与文本,不包裹 children)。其中processing状态带有一个循环扩散的脉冲动画。

title(悬浮提示):设置鼠标悬停在徽标上时显示的文字。默认情况下,若未显式传title,会取当前展示的数值作为 title(index.tsx)。参考 自定义标题演示,测试覆盖见 index.test.tsx。

color(自定义颜色):既可用于数字徽标(count 模式),也可用于状态点。支持两种写法:

  • 预设色名:pinkredyelloworangecyangreenbluepurplegeekbluemagentavolcanogoldlime(完整预设列表见 theme/interface/presetColors.ts);
  • 任意 CSS 颜色值:#f50rgb(...)hsl(...)hwb(...)均可。

参考 多彩徽标演示。源码中通过isPresetColor(color, false)(来自 _util/colors.ts)区分预设色与自定义色:预设色走genPresetColor生成的样式类(如.ant-badge-color-red),自定义色则以内联样式background/color直接写入(index.tsx)。

classNames / styles(语义化结构定制,5.7.0+):用于对 Badge 内部结构做细粒度样式定制,详见下文 Semantic DOM。

Badge.Ribbon API

Ribbon(缎带)通过Badge.Ribbon子组件使用,可将一个文本缎带贴在卡片等容器的右上角/左上角:

参数说明类型默认值版本
color自定义缎带的颜色string-
placement缎带的位置,startend随文字方向(RTL 或 LTR)变动start|endend
text缎带中填入的内容ReactNode-

参考 缎带演示:

<Badge.Ribbon text="Hippies"> <Card title="Pushes open the window" size="small"> and raises the spyglass. </Card> </Badge.Ribbon> <Badge.Ribbon text="Hippies" color="pink"> <Card title="Pushes open the window" size="small"> and raises the spyglass. </Card> </Badge.Ribbon>

从源码看(Ribbon.tsx),Ribbon 的实现要点:

  • placement默认'end',渲染类名${prefixCls}-placement-${placement}
  • 预设色复用isPresetColor判定生成-color-*类,自定义色直接写入background
  • 缎带主体与“折角”(corner)分离渲染:corner元素通过边框 +badgeRibbonCornerTransform: 'scaleY(0.75)'badgeRibbonCornerFilter: brightness(75%)实现立体折角效果(见 style/ribbon.ts);
  • RTL 环境下自动追加${prefixCls}-rtl类,start/end位置随文字方向对调(Ribbon.tsx)。

Semantic DOM

从 5.7.0 版本开始,Badge 提供语义化 DOM 结构,可通过classNamesstyles精确命中内部节点:

节点说明版本
root根节点5.7.0
indicator指示器节点(徽标数字/圆点本身)5.7.0

对应源码中的类型定义(index.tsx):

classNames?: { root?: string; indicator?: string; }; styles?: { root?: React.CSSProperties; indicator?: React.CSSProperties; };

参考 语义化结构演示。使用示例:

<Badge count={5} classNames={{ root: 'my-badge-root', indicator: 'my-badge-indicator' }} styles={{ indicator: { background: '#52c41a' } }} > <Avatar shape="square" size="large" /> </Badge>

源码中,classNames.rootstyles.root会被合并到根<span>上,classNames.indicatorstyles.indicator会被合并到内部状态点(status-dot)或滚动数字(scroll-number)节点上(index.tsx)。此外,ConfigProvider同样支持通过badge.classNames/badge.styles为全局 Badge 统一注入语义化样式。

主题变量(Design Token)

Badge 组件支持通过 ConfigProvider 的theme.components.Badge配置组件级 Token。参考 组件 Token 演示:

<ConfigProvider theme={{ components: { Badge: { indicatorHeight: 24, indicatorHeightSM: 18, dotSize: 4, textFontWeight: 'bold', statusSize: 8, }, }, }} > {/* ... */} </ConfigProvider>

组件级 Token 的完整定义与默认值见 style/index.ts 与prepareComponentToken(style/index.ts):

Token说明默认值计算
indicatorZIndex徽标 z-indexauto
indicatorHeight徽标高度Math.round(fontSize * lineHeight) - 2 * lineWidth
indicatorHeightSM小号徽标高度fontSize
dotSize点状徽标尺寸fontSizeSM / 2
textFontSize徽标文本尺寸fontSizeSM
textFontSizeSM小号徽标文本尺寸fontSizeSM
textFontWeight徽标文本粗细normal
statusSize状态徽标尺寸fontSizeSM / 2

同时 Badge 还依赖若干全局派生 Token(见prepareToken,style/index.ts),其中几个值得关注:

  • badgeColor:徽标默认背景色,取全局colorError(红色系),这也是数字徽标默认是红色的原因;
  • badgeColorHover:hover 时的背景色,取colorErrorHover
  • badgeTextColor:徽标文字颜色,取colorBgContainer(通常为白色);
  • badgeProcessingDurationprocessing状态脉冲动画周期,固定1.2s
  • badgeShadowSize/badgeShadowColor:徽标外圈描边(用 box-shadow 模拟细边框),取全局lineWidthcolorBorderBg

数字滚动动画原理

Badge 的数字切换带有一个逐位“滚动/翻牌”动画,这是它区别于普通角标的最大视觉特征。整体渲染链路为:

  1. 外层InternalBadge通过CSSMotion(rc-motion)控制徽标的出现/消失缩放动画(-zoom系列,motionDeadline={1000},见 index.tsx);
  2. 数字部分交由 ScrollNumber.tsx 渲染为<sup>元素,内部将数字字符串按字符拆分;
  3. 每个字符由 SingleNumber.tsx 负责逐位滚动:它先生成从旧值到新值的一段连续数字单位列表(UnitNumber),再通过transform: translateY(...)将容器偏移到目标位置,onTransitionEnd后收敛为静态单位。

关键实现细节(SingleNumber.tsx):

  • 仅对整数启用逐位滚动:count && Number(count) % 1 === 0(ScrollNumber.tsx),浮点数(如3.5)直接整体渲染;
  • 滚动方向由新旧 count 大小决定:unit = prevCount < count ? 1 : -1,并计算从旧值滚到新值的最短路径偏移getOffset
  • 若浏览器不支持 transitionend 事件,则用 1000ms 定时器兜底(SingleNumber.tsx);
  • 为了兼容旧用法<Badge count={4} style={{ borderColor: '#d9d9d9' }} />,当样式里带borderColor时,ScrollNumber 会用boxShadow: 0 0 0 1px borderColor inset模拟边框(ScrollNumber.tsx),对应测试见 index.test.tsx。

此外,出现/消失与 processing 脉冲动画均在样式文件中以 Keyframes 定义(antZoomBadgeIn/OutantNoWrapperZoomBadgeIn/OutantStatusProcessingantBadgeLoadingCircle,见 style/index.ts):processing状态通过::after伪元素循环scale(0.8 → 2.4)并渐隐实现呼吸扩散效果(style/index.ts)。

常用组合场景

独立使用(not-a-wrapper)

Badge 可以不包裹任何子元素独立存在(count 或 status 模式),此时自动追加ant-badge-not-a-wrapper类(index.tsx),样式上徽标不再绝对定位、而是作为行内元素参与布局(style/index.ts),并且缩放动画的原点变为自身中心。参考 独立使用演示:

<Badge count={show ? 11 : 0} showZero color="#faad14" /> <Badge count={show ? 25 : 0} />

动态切换

用 state 驱动 count 变化即可实现动态徽标,配合减/加/随机按钮体验数字滚动动画。参考 动态演示,其中用Switch控制dot的显隐,演示动画的进入与离开。注意源码中徽标隐藏后仍会缓存最后一次的 count 与 dot 状态(countRefdisplayCountRefisDotRef,见 index.tsx),避免离场动画期间数字闪变。

可点击

将 Badge 包进<a>即可实现整体可点击(link.tsx):

<a href="#"> <Badge count={5}> <Avatar shape="square" size="large" /> </Badge> </a>

样式文件同时定义了a:hover &下的背景变化(badgeColorHover),保证 hover 时徽标有反馈(style/index.ts)。

与 Tooltip 组合

Badge 可与 Tooltip 自由组合,例如在错误状态点上悬浮提示修复信息,相关测试见 index.test.tsx。

测试与验证

仓库为 Badge 提供了完整的测试覆盖,位于 components/badge/__tests__:

  • index.test.tsx:核心行为测试,包括 mount/rtl 基础测试、float/负数展示、dot 边界、自定义 title、offset 与 ReactNode count 组合、与 Tooltip 组合、数字变化动画快照、borderColor 兼容等;
  • ribbon.test.tsx:缎带行为测试;
  • demo.test.tsx 与 demo-extend.test.tsx:对全部官方 demo 的渲染与快照回归;
  • image.test.ts:视觉回归测试。

总结

Badge 虽是一个小组件,但信息密度很高:从 API 层面看,它同时支持数字徽标、小红点、状态点、多彩徽标与缎带五种形态;从实现层面看,它内部封装了 rc-motion 缩放动画、逐位数字滚动、RTL 适配、预设色系统与组件级 Design Token。理解 index.tsx 中count/overflowCount/showZero/dot的联动判定逻辑、SingleNumber.tsx 的滚动算法以及 style/index.ts 的 Token 体系,能帮助你在遇到定制需求时快速定位并优雅解决。

【免费下载链接】ant-designAn enterprise-class UI design language and React UI library项目地址: https://gitcode.com/gh_mirrors/ant/ant-design

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

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

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

立即咨询