Ant Design Statistic 单位添加指南:通过 prefix 与 suffix 为统计数值附加单位
【免费下载链接】ant-designAn enterprise-class UI design language and React UI library项目地址: https://gitcode.com/gh_mirrors/ant/ant-design
导读
在数据展示场景中,统计数值(Statistic)往往需要携带单位或修饰信息,例如"1128 个赞""93 / 100 条待合并"。本文基于 Ant Design 官方 demo(components/statistic/demo/unit.md 及对应实现 unit.tsx),系统讲解如何利用Statistic组件的prefix(前缀)与suffix(后缀)属性为数值附加单位,并结合源码剖析其渲染机制、格式化规则与样式细节。读完本文,你将掌握单位拼接、图标前缀、百分比/千分比后缀等常见用法,并能理解其在底层 DOM 结构与 Design Token 中的真实表现。
一、核心思路:前缀 + 后缀 = 单位
Ant Design 的Statistic(统计数值)组件专门用于"突出某个或某组数字"(见 components/statistic/index.zh-CN.md)。官方给出的"单位"demo 只有一句核心说明:
zh-CN:通过前缀和后缀添加单位。en-US: Add unit through
prefixandsuffix.
这句话点明了两种单位添加方式:
| 属性 | 含义 | 类型 | 默认值 | 典型用途 |
|---|---|---|---|---|
prefix | 设置数值的前缀 | ReactNode | - | 单位符号($、¥)、图标(如点赞图标) |
suffix | 设置数值的后缀 | ReactNode | - | 单位文本(/ 100、%、天)、说明文字 |
两个属性都接收任意ReactNode,意味着不仅可以放纯文本,还可以放图标、徽标甚至自定义组件,这与title(数值标题)、valueStyle(数值区域样式)等属性组合使用即可完成绝大多数统计卡片的单位呈现需求。
二、官方 Demo 完整代码
demo 的完整实现位于 components/statistic/demo/unit.tsx,它在一个两栏栅格中展示了前缀与后缀的典型用法:
import React from 'react'; import { LikeOutlined } from '@ant-design/icons'; import { Col, Row, Statistic } from 'antd'; const App: React.FC = () => ( <Row gutter={16}> <Col span={12}> <Statistic title="Feedback" value={1128} prefix={<LikeOutlined />} /> </Col> <Col span={12}> <Statistic title="Unmerged" value={93} suffix="/ 100" /> </Col> </Row> ); export default App;要点拆解:
- 左栏:
prefix={<LikeOutlined />}把@ant-design/icons中的点赞图标渲染在数值左侧,形成"👍 1128"的效果,适合点赞数、热度、评分等场景; - 右栏:
suffix="/ 100"把单位文本渲染在数值右侧,形成"93 / 100"的效果,适合进度占比、配额使用、评分总分等场景; - 外层使用
Row+Col span={12}实现两栏并排布局,gutter={16}控制列间距。
该 demo 同时被 components/statistic/index.zh-CN.md 的"代码演示"区以<code src="./demo/unit.tsx">单位</code>的方式引用,并在 demo.test.ts.snap 中固化了渲染快照,可用于回归验证。
三、底层实现:prefix / suffix 如何渲染
Statistic的主实现位于 components/statistic/Statistic.tsx。从组件解构可以看到相关属性的默认值与传递链路:
const { value = 0, title, valueRender, prefix, suffix, loading = false, /* --- FormatConfig starts --- */ formatter, precision, decimalSeparator = '.', groupSeparator = ',', /* --- FormatConfig starts --- */ ... } = props;在渲染阶段,数值区域由Skeleton包裹(支持loading骨架屏),其内部按"前缀 → 数值 → 后缀"的顺序输出三个独立节点:
<Skeleton paragraph={false} loading={loading} className={`${prefixCls}-skeleton`}> <div style={valueStyle} className={`${prefixCls}-content`}> {prefix && <span className={`${prefixCls}-content-prefix`}>{prefix}</span>} {valueRender ? valueRender(valueNode) : valueNode} {suffix && <span className={`${prefixCls}-content-suffix`}>{suffix}</span>} </div> </Skeleton>由此可以推断出以下实现事实:
- 条件渲染:
prefix/suffix仅在传值(truthy)时才渲染对应的<span>,未传时 DOM 中不会出现多余的占位节点; - 独立 CSS 类:前缀节点带有
ant-statistic-content-prefix类,后缀节点带有ant-statistic-content-suffix类(prefixCls默认经getPrefixCls('statistic')得到ant-statistic),便于样式定制与测试断言; valueRender的介入点:若传入valueRender,它包裹的是数值节点本身,前后缀仍保持在数值节点两侧,不会被打乱顺序;- 国际化友好:外层根节点根据
ConfigContext的direction自动追加-rtl类,RTL 布局下前缀/后缀的视觉位置由 CSS 逻辑属性(marginInlineEnd/marginInlineStart)自动镜像。
快照文件 demo.test.ts.snap 中固化渲染结果为:93位于ant-statistic-content-value-int内,/ 100位于紧随其后的ant-statistic-content-suffix内,与上述源码完全一致。
四、与数值格式化(FormatConfig)的组合运用
prefix/suffix只负责"单位外壳",数值本身的格式化由Statistic继承自FormatConfig的一组属性完成(定义见 components/statistic/utils.ts):
| 参数 | 说明 | 类型 | 默认值 |
|---|---|---|---|
decimalSeparator | 设置小数点 | string | . |
groupSeparator | 设置千分位标识符 | string | , |
precision | 数值精度 | number | - |
formatter | 自定义数值展示 | (value) => ReactNode | - |
当formatter未传入时,数值格式化由 components/statistic/Number.tsx 内部的StatisticNumber完成,其核心正则/^(-?)(\d*)(\.(\d+))?$/将数值拆分为"负号 + 整数 + 小数"三段:
- 整数部分通过
int.replace(/\B(?=(\d{3})+(?!\d))/g, groupSeparator)插入千分位分隔符; - 传入数字类型的
precision时,小数部分会先padEnd(precision, '0')补零再按精度截断; - 小数存在时用
decimalSeparator拼接小数点,输出拆分为-content-value-int与-content-value-decimal两个<span>。
因此,prefix/suffix与precision、groupSeparator完全正交,可以自由组合,例如同时展示"精确到两位小数 + 百分号后缀":
<Statistic title="任务完成率" value={0.8765} precision={2} suffix="%" />五、样式与 Design Token:单位的间距与字体
前缀/后缀的视觉呈现由 components/statistic/style/index.ts 中的 genStyleHooks 生成(CSS-in-JS)。关键样式规则如下:
[`${componentCls}-content`]: { color: colorTextHeading, fontSize: contentFontSize, fontFamily, [`${componentCls}-content-value`]: { display: 'inline-block', direction: 'ltr', }, [`${componentCls}-content-prefix, ${componentCls}-content-suffix`]: { display: 'inline-block', }, [`${componentCls}-content-prefix`]: { marginInlineEnd: marginXXS, }, [`${componentCls}-content-suffix`]: { marginInlineStart: marginXXS, }, },值得注意的细节:
- 单位与数值间距:前缀右侧(
marginInlineEnd)和后缀左侧(marginInlineStart)各留出marginXXS(约 4px)间距,且使用逻辑属性以兼容 RTL 场景; - 数值保持 LTR:
-content-value显式声明direction: 'ltr',保证数字(如千分位、小数点)在 RTL 语言环境下依然按左到右顺序阅读,而单位文本则跟随整体方向; - 字体与颜色继承:前缀、后缀与数值共同继承
-content的fontSize(contentFontSize,默认取fontSizeHeading3)与colorTextHeading,因此单位与数值天然视觉统一; - Token 定制入口:
prepareComponentToken暴露titleFontSize与contentFontSize两个组件 Token,可在 ConfigProvider 的theme.components.Statistic中覆盖以统一调整数值(含单位)的字号。
六、进阶场景与注意事项
1. 复杂 ReactNode 单位
由于prefix/suffix类型为ReactNode,单位可以是任意元素组合,例如带图标的复合后缀:
<Statistic title="增长人数" value={1280} prefix={<UserOutlined />} suffix={<span>人 <Tag color="green">较上月 +12%</Tag></span>} />2. 倒计时中的单位
Statistic.Countdown同样支持prefix/suffix/title/valueStyle(API 见 components/statistic/index.zh-CN.md),可用于在倒计时前后附加说明文字,例如prefix="距开奖"、suffix="后开奖"。其format参数参考 dayjs 的格式化语法(如HH:mm:ss),底层由 utils.ts 中的formatCountdown/formatTimeStr按Y/M/D/H/m/s/S单位逐级取整实现。
3. 与valueStyle配合
valueStyle作用于整个数值内容区(-content),即前缀、数值、后缀整体生效,可用它统一调整颜色、字号或添加加粗效果。
4. 注意 loading 状态
loading为true时,整个内容区(含前后缀)被Skeleton骨架屏替代,因此不要在依赖单位可见的场景下同时开启loading而遗漏骨架屏内的信息提示。
5. 测试与快照
修改前后缀的渲染结构时,可参考 components/statistic/tests/snapshots/demo.test.ts.snap 中的固化快照进行断言,确保-content-prefix/-content-suffix节点的输出顺序与内容符合预期。
小结
为 Ant DesignStatistic添加单位,本质上是利用prefix与suffix两个接收任意ReactNode的属性,在数值节点的两侧插入单位元素。结合源码可以看到:它们由 Statistic.tsx 条件渲染为带独立类名的<span>,数值格式化由 Number.tsx 与 utils.ts 协作完成,而间距、方向、字号等表现则由 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),仅供参考