首页
/ Ant Design Statistic 组件完全指南:统计数值、倒计时/正计时与语义化定制

Ant Design Statistic 组件完全指南:统计数值、倒计时/正计时与语义化定制

2026-09-08 17:26:56作者:咎岭娴Homer

导读:本文以 components/statistic/index.zh-CN.md 为骨架,系统讲解 Ant Design 中 Statistic(统计数值)组件的使用场景、完整 API、倒计时与正计时(Statistic.Timer)、语义化 DOM 与主题 Token 定制,并结合当前仓库源码解析数值格式化、计时刷新等底层实现,帮助你在数据看板、监控页、营销页中正确、高效地展示关键数字。

Statistic 是 Ant Design 数据展示组件族中的一员,专门用于突出展示单个或一组关键统计数字,例如用户量、成交额、完成率、剩余时间等。组件本身只负责“把数字好看地展示出来”,不承载任何数据请求逻辑,因此非常适合与大屏、Dashboard、Card、Descriptions 等布局自由组合。从当前仓库的目录结构看,Statistic 的完整实现位于 components/statistic,组件聚合入口在 index.tsx,其下挂载了 Statistic.Timer 与(已废弃的)Statistic.Countdown 两个子组件,与文档 index.zh-CN.md 描述的 API 一一对应。

何时使用 Statistic

官方文档明确了两种典型诉求:

  • 当需要突出某个或某组数字时使用,例如“今日销售额”“在线人数”“QPS”等;
  • 当需要展示带描述的统计类数据时使用,例如“完成率 98.3%”这类“描述 + 数值”的组合。

一句话:任何“标题 + 大号数字(可带单位、前后缀)”的展示需求,都是 Statistic 的用武之地。它本身不含图表、不含请求、不含交互逻辑,是纯展示型组件,这也是它能被嵌入 Card、Grid、Skeleton 等容器中自由组合的原因——从源码看,Statistic 在 loading 状态下直接复用了 Skeleton 组件来渲染占位骨架,见 Statistic.tsx

基础用法与常见场景

文档下的代码演示(components/statistic/demo/ 目录)覆盖了 7 类典型场景,几乎可以当作组件的“最小用例集”来阅读。

基本:标题 + 数值 + 精度

basic.tsx 展示最基本的用法:一个 title 加一个 value 即可完成一次统计展示;数值精度通过 precision 控制:

import { Button, Col, Row, Statistic } from 'antd';

const App: React.FC = () => (
  <Row gutter={16}>
    <Col span={12}>
      <Statistic title="Active Users" value={112893} />
    </Col>
    <Col span={12}>
      <Statistic title="Account Balance (CNY)" value={112893} precision={2} />
      <Button style={{ marginTop: 16 }} type="primary">Recharge</Button>
    </Col>
    <Col span={12}>
      <Statistic title="Active Users" value={112893} loading />
    </Col>
  </Row>
);

export default App;

可以看到几个关键点:

  • value 即数值内容,类型为 string | number
  • precision={2} 会将数值格式化为保留两位小数(不足补 0,超出截断,处理逻辑见后文源码分析);
  • loading 置为 true 时数值区域会以骨架屏呈现(该属性自 4.8.0 起提供)。

单位与前后缀:prefix / suffix

unit.tsx 演示了用 prefix 在数值前插入图标、用 suffix 在数值后插入单位文本的写法:

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 / suffix 的类型都是 ReactNode,因此既可以是字符串、图标,也可以是任意 React 节点。在源码 Statistic.tsx 中,这两个节点分别被包在 -content-prefix-content-suffix<span> 内,夹在数值两侧。

动画效果:自定义 formatter

animated.tsx 展示了如何借助 formatter 接入第三方数字滚动动画库 react-countup,实现“从 0 滚到目标值”的动效:

import CountUp from 'react-countup';
import type { StatisticProps } from 'antd';
import { Col, Row, Statistic } from 'antd';

const formatter: StatisticProps['formatter'] = (value) => (
  <CountUp end={value as number} separator="," />
);

// <Statistic title="Active Users" value={112893} formatter={formatter} />

这是 formatter 最常见的用法——当默认的静态数字格式无法满足需求(动画、自定义拼接、金额大写等)时,用 (value) => ReactNode 完全接管数值节点的渲染。源码 Number.tsx 会优先判断 formatter 是否为函数,若是则直接调用并把返回值作为数值节点。

在卡片中使用

card.tsx 将 Statistic 放进 Card 做成指标卡片,并用 styles.content + 颜色来区分涨跌(绿涨红跌):

import { ArrowDownOutlined, ArrowUpOutlined } from '@ant-design/icons';
import { Card, Col, Row, Statistic } from 'antd';

<Card variant="borderless">
  <Statistic
    title="Active"
    value={11.28}
    precision={2}
    styles={{ content: { color: '#3f8600' } }}
    prefix={<ArrowUpOutlined />}
    suffix="%"
  />
</Card>

这也是统计类页面的常见布局:外层用 Card / Row / Col 排版,内层用 Statistic 输出指标。需要说明的是,此处用到的是 v6 引入的语义化 styles(旧版写法 valueStyle 已被废弃,请用 styles.content 替代,源码在 Statistic.tsx 中会在开发环境下输出 valueStyle 的废弃告警)。

计时器:倒计时与正计时

timer.tsx 是文档重点介绍的 Statistic.Timer(5.25.0+)能力。它同时支持 countdown(倒计时,如活动结束、抢购剩余时间)与 countup(正计时,如页面已运行时长、通话时长):

import { Col, Row, Statistic } from 'antd';
import type { StatisticTimerProps } from 'antd';

const { Timer } = Statistic;

const deadline = Date.now() + 1000 * 60 * 60 * 24 * 2 + 1000 * 30; // Dayjs is also OK
const before = Date.now() - 1000 * 60 * 60 * 24 * 2 + 1000 * 30;

const onFinish: StatisticTimerProps['onFinish'] = () => {
  console.log('finished!');
};

const onChange: StatisticTimerProps['onChange'] = (val) => {
  if (typeof val === 'number' && !Number.isNaN(val) && 4.95 * 1000 < val && val < 5 * 1000) {
    console.log('changed!');
  }
};

<Timer type="countdown" value={deadline} onFinish={onFinish} />
<Timer type="countdown" title="Milliseconds" value={deadline} format="HH:mm:ss:SSS" />
<Timer type="countdown" title="Countdown" value={tenSecondsLater} onChange={onChange} />
<Timer type="countup" title="Countup" value={before} onChange={onChange} />
<Timer type="countdown" title="Day Level" value={deadline} format="D 天 H 时 m 分 s 秒" />

关键约定:

  • value毫秒时间戳countdown 模式下为目标时间(未来某刻),countup 模式下为起始时间(过去某刻);
  • 组件以约 60FPS(1000 / 60 ms,见 Timer.tsx)的间隔刷新展示;
  • onChange 回传当前剩余/已过毫秒数;onFinishcountdown 模式在归零后触发;
  • format 默认 HH:mm:ss,支持 DHmsS(毫秒)等时间单位,也支持中文字面量(见源码 formatTimeStr 的实现)。

自定义语义结构的样式和类

style-class.tsx 演示了 v6 语义化能力:classNamesstyles 既支持普通对象,也支持函数形式——函数会接收到 { props },从而可以根据当前 props(比如 value 正负)动态决定每个语义节点的样式:

const styleFn: StatisticProps['styles'] = ({ props }): GetProp<StatisticProps, 'styles', 'Return'> => {
  const numValue = Number(props.value ?? 0);
  const isNegative = Number.isFinite(numValue) && numValue < 0;
  if (isNegative) {
    return {
      title: { color: '#ff4d4f' },
      content: { color: '#ff7875' },
      value: { backgroundColor: '#fff1f0', borderRadius: 4, paddingInline: 6, userSelect: 'none' },
    };
  }
  return {};
};

<Statistic title="Yearly Loss" value={-18.7} precision={1} styles={styleFn} suffix="%" />

组件 Token(Design Token)定制

component-token.tsx 演示通过 ConfigProvidertheme.components.Statistic 统一修改组件的全局设计变量,无需逐例修改:

<ConfigProvider
  theme={{
    components: {
      Statistic: {
        titleFontSize: 20,
        contentFontSize: 20,
      },
    },
  }}
>
  {/* ...Statistic... */}
</ConfigProvider>

Statistic API

通用属性(className、style、id 等)参考 通用属性文档。Statistic 完整参数如下:

参数 说明 类型 默认值 版本
classNames 自定义组件内部各语义化结构的 class,支持对象或函数 Record<SemanticDOM, string> | (info: { props }) => Record<SemanticDOM, string> - 6.0.0
decimalSeparator 设置小数点 string . -
formatter 自定义数值展示 (value) => ReactNode - -
groupSeparator 设置千分位标识符 string , -
loading 数值是否加载中 boolean false 4.8.0
precision 数值精度(保留的小数位数) number - -
prefix 设置数值的前缀 ReactNode - -
styles 自定义组件内部各语义化结构的行内 style,支持对象或函数 Record<SemanticDOM, CSSProperties> | (info: { props }) => Record<SemanticDOM, CSSProperties> - 6.0.0
suffix 设置数值的后缀 ReactNode - -
title 数值的标题 ReactNode - -
value 数值内容 string | number - -
valueStyle 设置数值区域的样式已废弃,请使用 styles.content 替代 CSSProperties - -

补充说明:loading 依赖 Skeleton 实现;当 loading 与自定义 formatter 同时存在时,仍会先渲染 Skeleton 占位再替换为数值。valueStyle 在源码 Statistic.tsx 中被显式标记废弃并建议迁移到 styles.content

数值格式化的底层原理

如果不传 formatter,Statistic 会走内置的数字格式化逻辑(见 Number.tsx),主要做了三件事:

  1. 非法数字原样输出value 先被转成字符串,用正则 /^(-?)(\d*)(\.(\d+))?$/ 拆出符号、整数部分和小数部分,若匹配失败(如传了非数字字符串)则原样展示;
  2. 千分位分隔:对整数部分执行 int.replace(/\B(?=(\d{3})+(?!\d))/g, groupSeparator),即从右向左每三位插入 groupSeparator(默认 ,,可换成空格、_ 等);
  3. 小数精度处理:当传入 precision 时,小数部分 padEnd(precision, '0') 补零后截断到指定长度;decimalSeparator(默认 .)负责拼接小数点。最终整数与小数分别渲染为 -content-value-int-content-value-decimal 两个 <span>,为“整数、小数单独着色”之类的视觉需求预留了语义锚点。

同时,Formatter 类型还允许 'number' / 'countdown' 等内置取值,false 可关闭默认格式化,完整类型定义见 utils.ts

Statistic.Timer(倒计时 / 正计时)

自 5.25.0 起,官方推荐使用 Statistic.Timer 同时覆盖倒计时与正计时两种场景,替代旧的 Statistic.Countdown。文档中 <Badge>5.25.0+</Badge> 标识其引入版本。

参数 说明 类型 默认值 版本
type 计时类型,倒计时或正计时 countdown | countup - -
format 格式化展示,参考 dayjs 的格式串习惯 string HH:mm:ss -
prefix 设置数值的前缀 ReactNode - -
suffix 设置数值的后缀 ReactNode - -
title 数值的标题 ReactNode - -
value countdown 模式为目标时间、countup 模式为起始时间(毫秒时间戳) number - -
valueStyle 设置数值区域的样式 CSSProperties - -
onFinish 倒计时完成时触发;countup 模式下不生效 () => void - -
onChange 计时变化时触发 (value: number) => void - -

Timer 源码级运行机制

Timer.tsx 可以看到它的实现思路:

  • 刷新节奏UPDATE_INTERVAL = 1000 / 60,即以约 60FPS 调用 window.setInterval 驱动重渲染,保证秒针与毫秒展示都足够平滑;
  • 方向判定const down = type === 'countdown';每次 tick 计算 timeDiff = !down ? now - timestamp : timestamp - now,并通过 onChange 回传;
  • 终止条件:仅 countdown 且当 timestamp < now 时触发 onFinish() 并清除定时器,countup 永不触发 onFinish
  • 格式化:内部把计算出的差值交给工具函数 formatCounter(value, config, down),再由 formatTimeStr(duration, format)format 拆解为字符串(见 utils.ts)。格式串支持的占位符如下:
占位符 含义 单位置换值
Y 365 天
M 月(按 30 天折算) 30 天
D 24 小时
H 小时 60 分钟
m 分钟 60 秒
s 1000 毫秒
S 毫秒 1 毫秒

占位符支持重复字母以补零(如 HHss),多个连续同类字母按最长宽度补足前导 0;如需输出字面文本,可用方括号包裹(如 [天]),算法会先提取方括号内容再在结果中还原,见 utils.ts。这也是示例中 format="D 天 H 时 m 分 s 秒" 能正常展示中文的原因(字母占位符 + 普通中文字面量混排)。

此外,Timer 还通过 valueRender 在内部给数值节点去掉默认 title 提示,避免鼠标悬停时出现多余的 tooltip,细节见 Timer.tsx

Statistic.Countdown(已废弃)

版本 >= 5.25.0 时,请使用 Statistic.Timer(即 <Statistic.Timer type="countdown" />)作为替代方案。

Countdown 参数与 Timer 的 countdown 模式一致,完整 API 如下:

参数 说明 类型 默认值
format 格式化倒计时展示,参考 dayjs string HH:mm:ss
prefix 设置数值的前缀 ReactNode -
suffix 设置数值的后缀 ReactNode -
title 数值的标题 ReactNode -
value 数值内容(目标时间戳) number -
valueStyle 设置数值区域的样式 CSSProperties -
onFinish 倒计时完成时触发 () => void -
onChange 倒计时时间变化时触发 (value: number) => void -

从源码 Countdown.tsx 看,Countdown 本质上只是 StatisticTimer 的薄封装:它固定传 type="countdown",并在开发环境下输出 devUseWarning 的废弃提示,提示开发者迁移到 <Statistic.Timer type="countdown" />。因此阅读或维护旧代码时可以直接把 <Statistic.Countdown> 替换为 <Statistic.Timer type="countdown">,其余 formatonFinishonChange 等属性保持不变。而在聚合入口 index.tsx 中,Statistic.TimerStatistic.Countdown 都是作为静态属性挂在 Statistic 上的组合组件。

Semantic DOM(语义化节点)

v6 起 Statistic 暴露了完整的语义化 DOM 结构,方便在不触碰内部实现的前提下做精准的样式与类名定制。Statistic 提供以下语义节点:rootheadertitlecontentvalueprefixsuffix

结合源码 Statistic.tsx 的渲染结构与 demo/_semantic.tsx 中的语义说明,各节点的实际 CSS 类名与职责如下:

语义节点 对应类名(prefixCls 默认 ant-statistic 结构职责 版本
root ant-statistic 根容器,承载整体布局与重置样式 6.0.0
header ant-statistic-header 头部区域,包含标题的布局与下内边距 6.0.0
title ant-statistic-title 标题文字(颜色、字号等) 6.0.0
content ant-statistic-content 内容区,负责 prefix / value / suffix 的水平对齐 6.0.0
value ant-statistic-content-value 数值本体(字号、字重、字族、颜色) 6.4.0
prefix ant-statistic-content-prefix 数值前缀(inline-block、右外边距) 6.0.0
suffix ant-statistic-content-suffix 数值后缀(inline-block、左外边距) 6.0.0

value 节点内部还细分出 -content-value-int(整数部分)与 -content-value-decimal(小数部分)两个 span(见 Number.tsx),不过文档层面暴露的语义化入口以 value 为最小单位。各语义节点可通过 classNames(追加 class)与 styles(追加行内样式)以“对象”或“接收 { props } 的函数”两种形态进行定制,例如:

<Statistic
  title="Active Users"
  value={93241}
  styles={{
    title: { color: '#1890ff', fontWeight: 600 },
    content: { fontSize: '24px' },
    value: { color: '#0958d9', backgroundColor: '#e6f4ff', borderRadius: 4, paddingInline: 6 },
  }}
  suffix="users"
/>

主题变量(Design Token)

Statistic 支持通过 ConfigProvider 的组件级主题变量进行全局定制。可用 Token 定义于 style/index.ts,核心两个变量为:

Token 说明 默认值
titleFontSize 标题(title)的字号 fontSize(默认 14px)
contentFontSize 内容(数值区域)的字号 fontSizeHeading3(默认 24px)

对应的默认值来自 prepareComponentTokentitleFontSize: fontSizecontentFontSize: fontSizeHeading3,即标题默认沿用全局正文字号、数值默认使用三级标题字号(更大一号),从设计上保证“标题小、数值大”的阅读层级。使用时只需在应用根部包裹 ConfigProvider

<ConfigProvider
  theme={{
    components: {
      Statistic: { titleFontSize: 14, contentFontSize: 28 },
    },
  }}
>
  <App />
</ConfigProvider>

如需精确到组件或数值局部覆盖,则优先使用上文介绍的语义化 styles / classNames,二者共同构成“Token 全局定制 + 语义节点局部定制”的两层样式体系。

进阶提示与最佳实践小结

  1. 组件是无状态展示层:Statistic 不负责拉取数据,请自行在上层管理数据源;异步场景可结合 loading 提供骨架占位。
  2. 数字格式化优先走内置参数:千分位用 groupSeparator、小数位用 precision、单位用 prefix/suffix;只有动画、富文本等高级需求才需要自定义 formatter(参考 animated.tsx 中与 react-countup 的组合方式)。
  3. 倒计时请使用 Statistic.Timer:它同时支持 countdowncountup 双向计时,旧的 Statistic.Countdown 在 5.25.0 后已被废弃。
  4. 样式定制优先语义化节点:v6 中请使用 classNames / styles(含函数式动态样式),valueStyle 已废弃并会触发开发环境告警。
  5. 需要取到底层 DOM 时,可通过 ref 获取 nativeElement(类型 StatisticRef,见 Statistic.tsx),例如用于测量宽度或做滚动监听。

Statistic 组件结构清晰、扩展点集中,其语义化 DOM 设计在同类数据展示场景(如数值大盘、监控指标)中有很强的复用参考价值。若需要查看更多运行示例,可直接浏览 components/statistic/demo 目录下的各示例文件;相关自动化测试与快照覆盖见 components/statistic/tests,其中 semantic.test.tsx 可用于了解语义节点结构的断言方式。

登录后查看全文
热门项目推荐
相关项目推荐

项目优选

收起
kernelkernel
deepin linux kernel
C
33
18
ops-transformerops-transformer
本项目是CANN提供的transformer类大模型算子库,实现网络在NPU上加速计算。
C++
1.14 K
2.75 K
pytorchpytorch
作为 Ascend for PyTorch 社区的核心组件,TorchNPU 是昇腾专为 PyTorch 打造的深度学习适配插件,使 PyTorch 框架能够直接调用昇腾 NPU,为开发者提供昇腾 AI 处理器的超强算力。
Python
857
1.35 K
docsdocs
暂无描述
Markdown
898
5.82 K
ops-nnops-nn
本项目是CANN提供的神经网络类计算算子库,实现网络在NPU上加速计算。
C++
921
1.84 K
jiuwenswarmjiuwenswarm
JiuwenSwarm 是一款基于openJiuwen开发的智能AI Agent,它能够将大语言模型的强大能力,通过你日常使用的各类通讯应用,直接延伸至你的指尖。
Python
3.8 K
1.02 K
kernelkernel
openEuler内核是openEuler操作系统的核心,既是系统性能与稳定性的基石,也是连接处理器、设备与服务的桥梁。
C
531
596
cann-learning-hubcann-learning-hub
CANN 学习中心仓,支持在线互动运行、边学边练,提供教程、示例与优化方案,一站式助力昇腾开发者快速上手。
Jupyter Notebook
1.02 K
519
ops-mathops-math
本项目是CANN提供的数学类基础计算算子库,实现网络在NPU上加速计算。
C++
1.36 K
1.46 K
AscendNPU-IRAscendNPU-IR
AscendNPU-IR是基于MLIR(Multi-Level Intermediate Representation)构建的,面向昇腾亲和算子编译时使用的中间表示,提供昇腾完备表达能力,通过编译优化提升昇腾AI处理器计算效率,支持通过生态框架使能昇腾AI处理器与深度调优
C++
548
391