- 前端
- UI组件
【免费下载链接】rsuite
🧱 A suite of React components .
本文以 rsuite 的Progress进度条组件为对象,系统讲解其基础用法、状态控制(active/success/fail)、不确定加载动画、颜色尺寸定制、百分比位置、条纹效果、自定义信息内容与多段进度等能力。结合 Progress 官方文档、源码实现 与 测试用例,读者可掌握从最简单的百分比展示到磁盘占用可视化等完整实战方案。
组件概览与获取方式
Progress用于显示某个操作进度的状态,是 rsuite 中对加载、上传、存储空间等场景的通用可视化组件。从源码结构看,它是一个复合组件:Progress.Line(水平/垂直线条进度条)为默认形态,同时挂载了Progress.Circle(环形进度条)作为子组件,见 Progress.tsx。
import { Progress } from 'rsuite'; const App = () => <Progress percent={20} />;上述代码渲染一个进度为 20% 的水平进度条。组件同时导出ProgressLine,二者等价,均可直接使用(见 index.tsx)。
基础用法:默认水平进度条
不传入任何额外配置时,Progress显示一条水平进度条,进度由percent决定,默认值为0,百分比信息显示在进度条右侧:
import { Progress } from 'rsuite'; const App = () => <Progress percent={20} />;从源码 ProgressLine.tsx 可以看到,组件渲染结构为outer > trail > stroke三层,进度通过 CSS 变量--rs-progress-line-stroke注入内联样式,由样式表 _progress-line.scss 将width设置为该变量值,从而实现进度填充。
状态控制:active / success / fail
使用status属性指示进度所处的不同状态,可选值为'active'、'success'与'fail':
import { Progress, VStack, Text } from 'rsuite'; const App = () => ( <VStack spacing={10}> <Text>Active</Text> <Progress percent={30} status="active" /> <Text>Fail</Text> <Progress percent={50} status="fail" /> <Text>Success</Text> <Progress percent={100} status="success" /> </VStack> );三个状态的行为差异如下:
active:进度条上叠加一条白色高光做往复扫过动画(对应_progress-line.scss中的progress-active关键帧),表示任务正在进行;success:进度条与文字变为成功色(CSS 变量--rs-progress-bar-success),同时信息区默认渲染成功图标;fail:进度条与文字变为失败色(--rs-progress-bar-fail),信息区默认渲染失败图标。
状态图标的默认逻辑位于 ProgressInfo.tsx:当存在status且不为'active'时,使用PROGRESS_STATUS_ICON[status]渲染对应图标;否则显示纯文本百分比。源码层通过data-status属性将状态传递给样式层(ProgressLine.tsx),SCSS 依据该属性选择颜色与动画分支。
不确定状态:indeterminate
当进度百分比未知、只知道"操作正在进行"时,使用indeterminate属性渲染一段来回移动的动画,制造持续加载的观感:
import { Progress } from 'rsuite'; const App = () => { return <Progress indeterminate />; };实现细节:源码在indeterminate为真时强制将内部 stroke 的percent设为100(ProgressLine.tsx),并在根节点加上rs-progress-line-indeterminate类;样式层在 stroke 内部用::before伪元素绘制宽度 30% 的色块,通过progress-indeterminate关键帧以 1.5s 的周期循环移动(见 _progress-line.scss)。该特性自 6.0.0 版本加入。
颜色与尺寸定制
strokeColor:自定义进度条颜色
strokeColor不仅支持纯色,还支持 CSS 渐变字符串,可用于打造渐变进度条:
import { Progress, VStack } from 'rsuite'; const App = () => ( <VStack spacing={20}> <Progress percent={30} strokeColor="#673ab7" /> <Progress percent={30} strokeColor="linear-gradient(45deg, #4CAF50, #2196F3)" /> <Progress percent={50} strokeColor="linear-gradient(45deg, #2196F3,rgb(149, 243, 33))" trailColor="#000" /> </VStack> );源码中strokeColor被映射为 CSS 变量--rs-progress-line-color(ProgressLine.tsx),因此传入的linear-gradient(...)字符串可直接作为 background 值使用。同示例中的trailColor对应背景轨道色(--rs-progress-line-trail-color),可用来区分已填充与未填充区域。
strokeWidth 与 radius:调整高度与圆角
strokeWidth控制进度条的高度(线宽),radius自定义边框圆角,二者配合可获得圆角"胶囊"进度条:
import { Progress, VStack } from 'rsuite'; const App = () => ( <VStack spacing={10}> <Progress percent={30} strokeWidth={20} /> <Progress percent={30} strokeWidth={20} radius={10}/> </VStack> );从源码看,strokeWidth同时写入--rs-progress-line-size与--rs-progress-line-trail-size两个 CSS 变量(ProgressLine.tsx),分别控制 stroke 与 trail 的厚度,保证轨道和填充保持同一厚度;radius写入--rs-progress-line-radius,统一作用于 trail、stroke 及外层容器。radius的默认值取自设计变量--rs-radius-sm。若只传入strokeWidth而不传trailWidth,trail 会默认跟随 stroke 的厚度;trailWidth可单独覆盖轨道厚度。
百分比位置:percentPlacement
percentPlacement控制百分比指示器的位置,支持五个取值:'start'(左侧外部)、'end'(右侧外部,默认)、'insideStart'(内部靠左)、'insideEnd'(内部靠右)、'insideCenter'(内部居中):
import { Progress, VStack } from 'rsuite'; const App = () => ( <VStack spacing={20}> <Progress percent={30} percentPlacement="start" /> <Progress percent={30} percentPlacement="end" /> <Progress percent={30} percentPlacement="insideStart" strokeWidth={20} radius={10} /> <Progress percent={30} percentPlacement="insideEnd" strokeWidth={20} radius={10} /> <Progress percent={30} percentPlacement="insideCenter" strokeWidth={20} radius={10} /> </VStack> );注意:内部放置(inside*)需要足够的strokeWidth才能看清文字,因此示例中将strokeWidth提高到 20。实现上,组件通过percentPlacement?.startsWith('inside')判断信息区是渲染在 stroke 内部还是外部(ProgressLine.tsx),并将data-placement写到根节点(第 121 行),由 SCSS 依据该属性切换 flex 方向与内部对齐方式(_progress-line.scss)。
条纹效果:striped
striped为进度条叠加 45 度斜向条纹纹理;与status="active"组合时,条纹会持续滚动动画:
import { Progress, VStack } from 'rsuite'; const App = () => ( <VStack spacing={20}> <Progress percent={30} striped /> <Progress percent={30} striped status="active" /> <Progress percent={50} striped status="success" /> <Progress percent={50} striped status="fail" /> <Progress percent={70} striped status="active" strokeWidth={20} radius={10} percentPlacement="insideCenter" /> </VStack> );条纹由 stroke 的::after伪元素以linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent ...)绘制,background-size为 16px 的 CSS 变量--rs-progress-line-stripe-size;当同时处于active状态时,progress-stripe关键帧以 1s 线性循环驱动条纹平移(_progress-line.scss)。垂直模式下条纹角度自动切换为 -45 度。
自定义信息内容:renderInfo 与 showInfo
renderInfo:渲染比百分比更丰富的信息
renderInfo接收(percent, status)两个参数,返回任意 ReactNode,可用于展示完成文案、图标、自定义格式等:
import { Progress, VStack, HStack } from 'rsuite'; import { FaCheckCircle } from 'react-icons/fa'; const App = () => ( <VStack spacing={20}> <Progress percent={100} status="success" renderInfo={(percent, status) => ( <span style={{ color: status === 'success' ? '#4CAF50' : '#000' }} > {status === 'success' ? 'Completed!' : `${percent}%`} </span> )} /> <Progress percent={100} renderInfo={percent => ( <HStack> <FaCheckCircle color="#4CAF50" /> <span>{percent}% Done</span> </HStack> )} /> <Progress percent={60} percentPlacement="insideCenter" strokeWidth={20} radius={10} renderInfo={percent => `Current progress: ${percent}%`} /> </VStack> );从 ProgressInfo.tsx 可以看到优先级:renderInfo存在时优先调用它,否则根据status决定渲染状态图标还是纯百分比文本。
showInfo:隐藏文字信息
当只需要纯视觉进度、不需要任何文字时,设置showInfo={false}。典型场景是结合sections展示多段存储占用(见下文)。测试用例 ProgressLine.spec.tsx 验证了showInfo={false}时 DOM 中不会出现.rs-progress-line-info节点。
多段进度:sections
sections允许在同一根进度条上渲染多个不同颜色的分段,非常适合可视化磁盘空间占用、任务拆分或多指标对比:
import { Progress, VStack, HStack, Text, Divider } from 'rsuite'; const App = () => ( <VStack> <Progress sections={[ { percent: 15, color: '#f7635c' }, { percent: 40, color: '#ffb300' }, { percent: 15, color: '#409af5' } ]} /> <Divider /> <HStack justify="space-between" w="100%"> <Text>Macintosh HD</Text> <Text>Used: 750 GB / 1 TB</Text> </HStack> <Progress strokeWidth={20} radius={10} showInfo={false} sections={[ { percent: 15, color: '#f7635c', label: 'Applications', tooltip: 'Apps: 150 GB' }, { percent: 20, color: '#f08800', label: 'Documents', tooltip: 'Documents: 200 GB' }, { percent: 40, color: '#717273', label: 'System Data', tooltip: 'System Data: 400 GB' }, { percent: 25, color: '#b6b7b8', label: '250 GB', tooltip: 'Unused: 250 GB' } ]} /> </VStack> );每个分段由ProgressSection接口描述(types.ts):
interface ProgressSection { /** Percent of this section */ percent: number; /** Color of this section */ color: string; /** Label of this section */ label?: React.ReactNode; /** Tooltip of this section */ tooltip?: React.ReactNode; }字段说明:
percent:该分段占整条进度条的百分比,所有分段之和即总进度;color:分段颜色,直接作用于该段背景;label(可选):显示在分段内部的文字标签;tooltip(可选):悬停分段时通过 Whisper + Tooltip 弹出的提示内容。
实现原理(ProgressSections.tsx):组件按顺序遍历sections,为每段创建一个ProgressStroke,并通过累加countPercent计算每段的bottom偏移(垂直模式),从而按比例堆叠。总进度为各段percent之和,同步反映在aria-valuenow上(ProgressLine.tsx)。分段样式对首段与末段分别应用起始端/结束端圆角(_progress-line.scss)。
垂直进度条:vertical
vertical将进度条旋转为自下而上的垂直方向,status、strokeColor、percentPlacement、sections等所有属性均继续适用:
import { Progress, HStack } from 'rsuite'; const App = () => ( <HStack h={300} spacing={32} wrap> <Progress vertical /> <Progress vertical percent={30} status="active" /> <Progress vertical percent={50} status="fail" /> <Progress vertical percent={100} status="success" /> <Progress vertical indeterminate /> <Progress vertical percent={80} showInfo={false} /> <Progress vertical percent={30} percentPlacement="start" /> <Progress vertical percent={30} percentPlacement="end" /> <Progress vertical percent={60} percentPlacement="insideStart" strokeWidth={20} radius={10} /> <Progress vertical percent={60} percentPlacement="insideEnd" strokeWidth={20} radius={10} /> <Progress vertical percent={60} percentPlacement="insideCenter" strokeWidth={20} radius={10} /> <Progress vertical strokeWidth={20} radius={10} showInfo={false} sections={[ { percent: 40, color: '#f7635c', label: 'Documents' }, { percent: 30, color: '#f08800', label: 'Media' }, { percent: 30, color: '#409af5', label: 'Applications' } ]} /> </HStack> );垂直模式样式位于 _progress-line.scss:轨道(trail)最小高度 100px,stroke 改为按height百分比填充且transform: rotate(180deg)(实现自下而上生长);percentPlacement在垂直模式下的语义映射为:start底部、end顶部(默认),inside*则按 start/end/center 垂直对齐。垂直模式下内部信息文字通过 mixin 旋转 90 度竖排显示。注意:垂直进度条默认宽度自适应(width: auto),实际占位高度由外层容器(如示例中的h={300})决定。
Props 完整参考
<Progress>
| 属性名称 | 类型 (默认值) | 描述 | 版本 |
|---|---|---|---|
| classPrefix | string('progress-line') | 组件 CSS 类的前缀 | |
| indeterminate | boolean | 显示不确定状态的加载动画 | 6.0.0 |
| percent | number(0) | 进度百分比 | |
| percentPlacement | 'start' | 'end' | 'insideStart' | 'insideEnd' | 'insideCenter'('end') | 百分比信息的显示位置 | 6.0.0 |
| radius | number | string | 进度条的圆角半径 | 6.0.0 |
| renderInfo | (percent: number, status?: 'success' | 'fail' | 'active') => ReactNode | 自定义信息内容的渲染函数 | 6.0.0 |
| sections | ProgressSection[] | 具有不同颜色的多个进度段 | 6.0.0 |
| showInfo | boolean(true) | 是否显示文字 | |
| status | 'success' | 'fail' | 'active' | 进度状态 | |
| striped | boolean | 是否显示条纹效果 | 6.0.0 |
| strokeColor | string | 线条颜色 | |
| strokeWidth | number | 线条宽度 | |
| trailColor | string | 背景颜色 | |
| trailWidth | number | 背景宽度 | |
| vertical | boolean | 垂直显示进度条 | |
| width | number | 圆直径(对应Progress.Circle环形进度条的尺寸参数) |
其中indeterminate、percentPlacement、radius、renderInfo、sections、striped均为 6.0.0 版本新增能力。ProgressSection类型由 src/Progress/types.ts 定义并随组件导出。
无障碍与源码细节
ProgressLine在 DOM 层面遵循 WAI-ARIA 进度条规范:根节点带有role="progressbar"、aria-valuemin="0"、aria-valuemax="100"与aria-valuenow(取sections总和或percent),并携带data-status、data-placement供样式与测试断言使用(ProgressLine.tsx)。测试用例 ProgressLine.spec.tsx 覆盖了百分比注入、strokeWidth生成的 CSS 变量、状态/垂直/条纹/不确定类名以及showInfo开关等关键行为;多段进度的累积计算另有 ProgressLineSections.spec.tsx 验证。
若需要环形进度条,可使用Progress.Circle,其实现位于 src/ProgressCircle/ProgressCircle.tsx,与Progress.Line共享ProgressInfo等内部件,width(圆直径)即为其专属参数。
综上,Progress从最简单的percent百分比展示,到sections多段堆叠、indeterminate未知加载、vertical垂直布局与striped动态条纹,覆盖了绝大多数业务进度可视化需求;配合renderInfo可将信息区扩展为任意自定义内容,值得在加载、上传、存储展示等场景中直接复用。
- 前端
- UI组件
【免费下载链接】rsuite
🧱 A suite of React components .
相关推荐
Lenis平滑滚动完整指南:3行代码实现60fps丝滑体验
Lenis平滑滚动完整指南:3行代码实现60fps丝滑体验 Lenis 是一个几 KB 的平滑滚动库(让页面滚动不再一格一格地跳,而是像丝一样滑过去)。它不是"
前端UI组件Bubble Tea 动画进度条实战:用 progress 组件实现平滑过渡的 TUI 进度显示
Bubble Tea 动画进度条实战:用 progress 组件实现平滑过渡的 TUI 进度显示 本篇文章以 Bubble Tea 仓库中的 progress
CLI跨平台Smooth水平进度条多线段流动效果配置:progress-bar-cj进阶完全指南
Smooth水平进度条多线段流动效果配置:progress bar cj进阶完全指南 progress bar cj 是用仓颉语言开发的鸿蒙自定义进度条组件库,
后端ORM
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考