尧图网络科技YAOTU DIGITAL 获取报价
获取报价
首页 / 资讯中心 / 文章详情

Semi Design Progress 进度条组件完全指南:从基础用法到源码级实现原理

发布时间:2026/9/24 16:15:40

资讯中心
01
ARTICLE

Semi Design Progress 进度条组件完全指南:从基础用法到源码级实现原理

Semi Design Progress 进度条组件完全指南:从基础用法到源码级实现原理
前端UI组件设计系统【免费下载链接】semi-designA modern, comprehensive, flexible design system and React UI library, AI-friendly built-in.Provide 3000 Design Tokens, easy to build your design system. Make Semi Design to Any Design.‍ Design to Code in one click项目地址https://gitcode.com/gh_mirrors/se/semi-design点击查看免费下载Semi Designdouyinfe/semi-ui的 Progress 组件用于展示用户操作的当前进度与状态既适合长耗时操作的过程反馈也能直观表示任务或对象的完成度。本文以 Progress 官方文档 为主体结合 组件源码、Foundation 层实现 与 单元测试系统讲解条状line与环形circle两种进度条的完整用法、全部 API 参数、无障碍ARIA实践以及分段配色、自动渐变、不确定状态等高级特性的底层实现原理帮助你在实际项目中快速落地并深度定制进度反馈。组件定位与引入方式Progress 属于反馈类Feedback组件适用于上传、下载、安装、复制等耗时操作的进度展示也可用于统计型任务的完成度指标。它同时支持两种形态条状进度条line默认形态横向或纵向铺满容器环形进度条circleSVG 绘制的圆环默认尺寸 72 × 72。通过 npm 包中导出的方式引入即可使用import { Progress } from douyinfe/semi-ui;从源码看组件以Progress为类名在 semi-ui 的入口 中统一导出属于 React 类组件Class Component样式通过douyinfe/semi-foundation/progress/progress.scss自动引入无需额外手动加载 CSS。基础用法标准进度条标准进度条通过三个核心属性控制外观与进度stroke进度条填充色percent已完成的进度百分比0 ~ 100size进度条尺寸可选default/small/largearia-label说明进度条具体代表的含义提升无障碍体验。如果size预设的尺寸不满足需求可通过style传入height自定义进度条高度import React from react; import { Progress } from douyinfe/semi-ui; () ( div style{{ width: 200 }} Progress percent{10} strokevar(--semi-color-warning) aria-labeldisk usage / br / Progress percent{25} strokevar(--semi-color-danger) aria-labeldisk usage / br / Progress percent{50} aria-labeldisk usage/ br / Progress percent{80} aria-labeldisk usage/ br / Progress percent{80} sizelarge aria-labeldisk usage/ br / Progress percent{80} style{{ height: 8px }} aria-labeldisk usage/ /div );从 Foundation 样式源码 可以看到默认尺寸的底层定义水平进度条默认高度为 4px$height-progress_horizontallarge尺寸为 6px$height-progress_horizontal_large默认填充色为var(--semi-color-success)轨道背景色为var(--semi-color-fill-0)。因此上述示例中strokevar(--semi-color-warning)本质上是在覆盖 CSS 变量可随主题自动切换。自定义高度与百分比越界处理除了style自定义高度外percent超出范围时组件会自动钳制。源码中的calcPercent方法见 index.tsx将大于 100 的值收敛为 100、小于 0 的值收敛为 0对应测试 progress.test.js 验证了传入 101 显示100%、传入 -2 显示0%的行为。同时若percent传入NaNcomponentDidUpdate会抛出[Semi Progress]:percent can not be NaN异常测试中也对该场景做了断言。不确定状态进度条当任务进度无法计算时如等待服务端响应、加载资源阶段设置indeterminate展示不确定状态。该属性对条状和环形进度条均生效开启后percent不再控制进度长度且showInfo文本被隐藏import React from react; import { Progress } from douyinfe/semi-ui; () ( div style{{ width: 240 }} Progress indeterminate aria-labelLoading / br / Progress indeterminate sizelarge aria-labelLoading / div style{{ display: flex, alignItems: center, gap: 16, marginTop: 20 }} Progress indeterminate typecircle aria-labelLoading / Progress indeterminate typecircle sizesmall aria-labelLoading / /div /div );不确定状态的底层实现从源码看不确定状态并非通过 JS 不断改写宽度而是纯 CSS 动画驱动条状水平semi-progress-indeterminate-slide动画让一个宽度为 35% 的滑块在轨道内循环滑动动画时长 1.6s、缓动ease-in-out见 progress.scss 与 keyframes 定义条状垂直使用semi-progress-indeterminate-slide-vertical沿 Y 轴滑动环形弧长固定为圆周长的 30%strokeDasharray circumference * 0.3配合semi-progress-indeterminate-rotate匀速旋转动画时长 1.2s。关键渲染逻辑在 index.tsx 的 renderCircleProgressindeterminate为真时strokeDashoffset固定为 0strokeDasharray固定为0.3 * circumferencepercent被完全忽略。测试 progress.test.js 精确断言了弧长占比为 0.3、aria-valuenow不设置、百分比文本不渲染等行为。显示与格式化百分比文本默认情况下进度条不显示百分比文本showInfo默认为false。通过showInfo{true}控制是否展示条状进度条显示在右侧环形进度条显示在圆心。format函数可自定义文本内容参数为当前百分比import React from react; import { Progress } from douyinfe/semi-ui; () ( div style{{ width: 200 }} Progress percent{10} strokevar(--semi-color-warning) showInfo{true} aria-labeldisk usage/ br / Progress percent{25} strokevar(--semi-color-danger) showInfo{true} aria-labeldisk usage/ br / Progress percent{50} showInfo{true} aria-labeldisk usage/ br / Progress percent{50} showInfo{true} format{percent percent * 10 ‰} aria-labeldisk usage/ /div );默认的format为(text) ${text}%见 index.tsx 的 defaultProps即直接拼接百分号。format的返回值类型为ReactNode因此不仅支持字符串也支持返回任意 React 节点。测试 progress.test.js 中format: () semi验证了自定义文本直接渲染进圆心。数值动画showInfo展示的数字并非直接跳变。源码中通过semi-animation的Animation实例在percent变化时以线性缓动、300ms 时长驱动percentNumber状态从旧值过渡到新值见 index.tsx实现数字滚动效果。若传入motion{false}则关闭动画、立即更新对应测试 progress.test.js。注意组件卸载时会销毁动画实例并置_mounted false避免卸载后 setState 报错。垂直进度条通过directionvertical切换为纵向条状进度条。默认宽度为 4pxlarge尺寸为 6px见 variables.scss如需自定义宽度通过style传入widthimport React from react; import { Progress } from douyinfe/semi-ui; () ( div style{{ height: 100, display: flex }} Progress percent{10} directionvertical aria-labeldisk usage/ Progress percent{25} directionvertical aria-labeldisk usage/ Progress percent{50} directionvertical aria-labeldisk usage/ Progress percent{80} directionvertical sizelarge aria-labeldisk usage/ Progress percent{80} directionvertical style{{ width: 8px }} aria-labeldisk usage/ /div );从 renderLineProgress 的实现看垂直模式下进度通过innerStyle.height perc %控制水平模式则设置innerStyle.width。SCSS 中垂直容器使用flex-direction: column布局百分比文本位于进度条下方margin-top间距定义见 variables.scss。环形进度条设置typecircle后进度条以圆环形态展示默认尺寸 72 × 72import React from react; import { Progress } from douyinfe/semi-ui; () ( div Progress percent{10} typecircle style{{ margin: 5 }} aria-labeldisk usage/ Progress percent{25} typecircle style{{ margin: 5 }} aria-labeldisk usage/ Progress percent{50} typecircle style{{ margin: 5 }} aria-labeldisk usage/ Progress percent{80} typecircle style{{ margin: 5 }} aria-labeldisk usage/ /div );通过width属性控制环形进度条尺寸import React from react; import { Progress } from douyinfe/semi-ui; () ( React.Fragment div Progress percent{100} typecircle width{100} style{{ margin: 5 }} aria-labeldisk usage/ /div div Progress percent{100} typecircle width{100} style{{ margin: 5 }} stroke#f93920 aria-labeldisk usage/ /div /React.Fragment );小尺寸环形进度条sizesmall仅对typecircle生效默认尺寸为 24 × 24import React from react; import { Progress } from douyinfe/semi-ui; () ( React.Fragment Progress percent{10} typecircle sizesmall style{{ margin: 5 }} aria-labeldisk usage/ Progress percent{25} typecircle sizesmall style{{ margin: 5 }} aria-labeldisk usage/ Progress percent{50} typecircle sizesmall style{{ margin: 5 }} aria-labeldisk usage/ Progress percent{80} typecircle sizesmall style{{ margin: 5 }} aria-labeldisk usage/ /React.Fragment );环形尺寸的判定逻辑在 index.tsx优先使用width属性未传时size default取 72、否则取 24。小尺寸下无论showInfo为何值圆心文本都不会渲染见 index.tsx。环形进度的 SVG 绘制原理环形进度条基于 SVGcircle实现半径radius (width - strokeWidth) / 2周长circumference radius * 2 * Math.PI。前景弧线通过stroke-dashoffset (1 - percent / 100) * circumference控制已完成长度stroke-width由strokeWidth属性控制默认 4起始点通过 SCSS 中transform: rotate(-90deg)从 12 点方向开始见 progress.scss。测试 progress.test.js 验证了width会直接映射到 SVG 的宽高属性。圆角 / 方角边缘通过strokeLinecap控制环形进度条的端点形状可选round圆角默认与square方角该属性仅在typecircle模式下生效import React from react; import { Progress } from douyinfe/semi-ui; () ( React.Fragment Progress percent{50} strokeLinecapround typecircle style{{ margin: 10 }} aria-labeldisk usage/ Progress percent{50} strokeLinecapsquare typecircle style{{ margin: 10 }} aria-labeldisk usage/ /React.Fragment );strokeLinecap会被直接透传到 SVGcircle的stroke-linecap属性见 renderCircleProgress默认值为round可选值在 constants.ts 中定义为[square, round]。自定义进度条颜色与分段配色stroke属性除了接收字符串颜色外还支持传入颜色分段数组Array{ percent: number; color: string }为不同进度区间配置不同颜色。color支持Hex、Hsl、Hsla、Rgb、Rgba以及 Semi Design Tokens如orange-9import React, { useState } from react; import { Progress, Button } from douyinfe/semi-ui; import { IconChevronLeft, IconChevronRight } from douyinfe/semi-icons; () { const [percent, setPercent] useState(10); const strokeArr [ { percent: 20, color: red }, { percent: 40, color: orange-9 }, { percent: 60, color: light-green-8 }, { percent: 80, color: hsla(125, 50%, 46% / 1) } ]; return ( div Progress percent{percent} stroke{strokeArr} showInfo typecircle width{100} aria-labeldisk usage / Progress percent{percent} stroke{strokeArr} showInfo style{{ margin: 20px 0 10px }} aria-labeldisk usage / /div Button icon{IconChevronLeft /} themelight onClick{() { setPercent(percent - 10); }} disabled{percent 0} / Button icon{IconChevronRight /} themelight onClick{() { setPercent(percent 10); }} disabled{percent 100} / / ); };分段着色的解析算法分段颜色的核心算法位于 generates.ts。generate函数按percent升序排序分段然后当前百分比小于第一个分段点返回默认成功色var(--semi-color-success)当前百分比大于最后一个分段点返回最后一个分段的颜色命中某个分段点直接返回该颜色落在两个分段点之间且strokeGradient为false取上一段颜色。测试 progress.test.js 验证了strokeGradient: false时 90% 落在 3% 分段之后取该段白色#ffffffff。同时formatToHex会先把Hex/Hsl(a)/Rgb(a)/ Semi Design Tokens 统一转换为带 Alpha 通道的 8 位十六进制色值其中 Token 通过getComputedStyle(document.body).getPropertyValue(--semi-xxx)读取 CSS 变量仅浏览器环境下生效见 generates.tsSemi 的 16 个序列色板blue、red、green、orange 等见 SEMI_DESIGN_TOKENS会在未指定序号时默认取-5档位。自动补齐颜色区间渐变设置strokeGradient{true}后落在两个分段点之间的百分比会自动生成平滑渐变色要求stroke至少提供一个颜色区间import React, { useEffect, useState } from react; import { Space, Progress, Button } from douyinfe/semi-ui; import { IconChevronLeft, IconChevronRight } from douyinfe/semi-icons; () { const [percent, setPercent] useState(65); const [percentInterval, setPercentInterval] useState(0); useEffect(() { setTimeout( () { setPercentInterval(percentInterval 100 ? 0 : percentInterval 3); }, percentInterval 0 || percentInterval 100 ? 1200 : 290 - (percentInterval % 50) * 3 ); }, [percentInterval]); const strokeArr [ { percent: 0, color: rgb(249, 57, 32) }, { percent: 50, color: #46259E }, { percent: 100, color: hsla(125, 50%, 46% / 1) }, ]; const strokeArrReverse [ { percent: 0, color: hsla(125, 50%, 46% / 1) }, { percent: 50, color: #46259E }, { percent: 100, color: rgb(249, 57, 32) }, ]; return ( Space spacing{20} div Progress percent{percentInterval} stroke{strokeArr} strokeGradient{true} showInfo typecircle width{100} aria-labelfile download speed / /div div Progress percent{percentInterval} stroke{strokeArrReverse} strokeGradient{true} showInfo typecircle width{100} aria-labelfile download speed / /div /Space div style{{ width: 100%, margin: 20px 0 10px }} Progress percent{percent} stroke{strokeArr} strokeGradient{true} showInfo sizelarge aria-labelfile download speed / /div Button icon{IconChevronLeft /} themelight onClick{() { setPercent(percent - 5); }} disabled{percent 0} / Button icon{IconChevronRight /} themelight onClick{() { setPercent(percent 5); }} disabled{percent 100} / / ); };渐变插值原理generateGradients函数见 generates.ts把两端颜色拆解为 R、G、B、A 四个通道按区间长度等步长插值再拼接成 8 位十六进制颜色返回。测试 progress.test.js 对strokeGradient: true且 percent 落在 50% 与 52% 之间的场景断言结果为#8080807f证明插值计算精确可用另一用例 则验证了 Hex、Rgb、Hsla、命名色混用的兼容性55% 落在 50% 与 100% 之间时取#066b9dff。自定义圆心文本内容环形进度条圆心文本可通过format函数完全自定义参数为当前百分比返回值会直接渲染在圆心若不需要圆心文本可将showInfo设为false或在format中直接返回空字符串import React from react; import { Progress } from douyinfe/semi-ui; () ( React.Fragment Progress percent{75} showInfo typecircle format{per per Days} style{{ margin: 10 }} aria-labeldisk usage/ Progress percent{100} showInfo typecircle format{per Done} style{{ margin: 10 }} aria-labeldisk usage/ Progress percent{50} typecircle showInfo{false} style{{ margin: 10 }} aria-labeldisk usage/ /React.Fragment );动态变化百分比Progress 是受控组件percent变化会触发内部动画与重绘。配合 Button 即可实现动态增减进度的交互条状与环形均可import React from react; import { Progress, Button } from douyinfe/semi-ui; import { IconChevronLeft, IconChevronRight } from douyinfe/semi-icons; () { const [percent, setPercent] useState(40); return ( div Progress percent{percent} showInfo / Button icon{IconChevronLeft /} themelight onClick{() { setPercent(percent - 10); }} disabled{percent 0} / Button icon{IconChevronRight /} themelight onClick{() { setPercent(percent 10); }} disabled{percent 100} / /div / ); };import React from react; import { Progress, Button } from douyinfe/semi-ui; import { IconChevronLeft, IconChevronRight } from douyinfe/semi-icons; () { const [cirPerc, setCirPerc] useState(40); return ( div div Progress percent{cirPerc} typecircle aria-labeldisk usage/ /div Button icon{IconChevronLeft /} themelight onClick{() { setCirPerc(cirPerc - 10); }} disabled{cirPerc 0} / Button icon{IconChevronRight /} themelight onClick{() { setCirPerc(cirPerc 10); }} disabled{cirPerc 100} / /div ); };从源码看componentDidUpdate中对比新旧percent在motion开启时创建semi-animation的Animation实例用 300ms 线性动画驱动数值与进度平滑过渡index.tsx同时 SCSS 也为条状进度的width/height和环形进度的stroke-dashoffset定义了 0.3s 的 transitioncubic-bezier(0.62, 0.05, 0.36, 0.95)见 variables.scss保证视觉过渡流畅。API Reference以下为 Progress 全部属性基于 官方文档 整理属性说明类型默认值aria-labelaria-label 属性为当前元素添加标签描述以提升 a11yv2.2.0 起提供stringaria-labelledbyaria-labelledby 属性表明某些元素的 id 是当前元素的标签用于建立控件组与其标签的关联以提升 a11yv2.2.0 起提供stringaria-valuetextaria-valuetext 属性用于提升 a11yv2.2.0 起提供stringclassName样式类名stringdirection条状进度条的方向horizontal/verticalstringhorizontalidid 属性v2.2.0 起提供stringformat格式化函数入参为当前百分比返回值直接渲染在环形进度条圆心(percent: number) ReactNode(percent) percent %indeterminate是否展示不确定状态进度条。开启后percent不再控制进度长度showInfo文本隐藏booleanfalseorbitStroke进度条轨道填充色v1.0.0 起提供stringvar(--semi-color-fill-0)percent进度百分比numbershowInfo环形进度条是否显示圆心文本、条状进度条是否显示右侧文本booleanfalsesize尺寸可选default、small仅 typecircle 生效、large仅 typeline 生效stringdefaultstroke进度条填充色。当类型为Array{percent:number; color:string}时color支持Hex|Hsl|Hsla|Rgb|Rgba|Semi Design Tokensstring | Array{percent:number; color:string}var(--semi-color-success)strokeGradient是否自动生成渐变色填补颜色区间需要stroke至少设置一个颜色区间booleanfalsestrokeLinecap圆角round/ 方角square仅 typecircle 生效stringroundstrokeWidth当 type 为circle时控制进度条宽度number4style样式CSSPropertiestype类型可选line/circlestringlinewidth环形进度条宽度numbersizedefault 时为 72small 时为 24这些默认值在 index.tsx 的 defaultProps 与 constants.ts 中均有对应定义且支持通过全局 ConfigProvider 覆盖默认属性源码使用getDefaultPropsFromGlobalConfig包装。Accessibility 无障碍Progress 在无障碍方面遵循 W3C ARIA 进度条规范实现细节可从 renderLineProgress 与 renderCircleProgress 确认组件根节点带有roleprogressbar角色标明其进度条语义自动设置aria-valuemin{0}、aria-valuemax{100}自动将percent写入aria-valuenow保证屏幕阅读器能读取正确的百分比当indeterminatetrue时省略aria-valuenow当前进度未知支持传入aria-valuetext按 W3C 规范传入后屏幕阅读器会优先消费aria-valuetext而非aria-valuenow支持aria-label与aria-labelledby当 Progress 外部存在描述性元素时可通过aria-labelledby显式指定该元素 id 作为进度条标签否则应使用aria-label说明 Progress 数值的具体含义。// good case p idprogressbar-labelDisk Usage/p Progress aria-labelledbyprogressbar-label percent{80} / // good case Progress aria-labelPercent of disk usage percent{80} / Progress aria-labelPercent of file downloaded percent{80} / // usage of aria-valuetext Progress aria-labelPercent of disk usage percent{80} aria-valuetextStep 2: Copying files... /Content Guidelines 内容规范如果进度条过程复杂或等待时间较长可配合辅助说明文字help text解释当前正在进行的操作让用户清楚进度背后的具体内容。例如结合aria-valuetext或组件外部的文案描述“正在复制文件”等阶段信息。Design Tokens 设计变量Progress 的颜色、尺寸、间距全部通过设计变量Design Tokens驱动方便跟随主题定制。核心变量定义在 variables.scss颜色轨道背景var(--semi-color-fill-0)、默认进度色var(--semi-color-success)、条状文本色var(--semi-color-text-0)、环形文本色var(--semi-color-mode-minor-text)尺寸水平条高度 4px / large 6px垂直条宽度 4px / large 6px百分比文本最小宽度 45px圆角轨道与进度条均为var(--semi-border-radius-small)动画过渡时长 0.3s缓动曲线cubic-bezier(0.62, 0.05, 0.36, 0.95)。另外 rtl.scss 提供了 RTL从右到左布局适配在semi-rtl/semi-portal-rtl容器内条状进度条文本的 margin 方向翻转环形文本从left: 50%切换为right: 50%而环形进度起始点仍保持从 12 点方向绘制确保阿拉伯语等 RTL 语系下的展示一致性。小结Semi Design 的 Progress 组件在 API 设计上覆盖了进度反馈的绝大多数场景条状/环形双形态、大小尺寸、方向切换、百分比格式化、分段配色、自动渐变、不确定状态以及完整且规范的 ARIA 无障碍支持。其底层实现也颇具参考价值——环形进度基于 SVGstroke-dasharray/stroke-dashoffset计算分段配色与渐变通过 generates.ts 的通道级插值算法完成不确定状态则由纯 CSS Keyframes 驱动动画与数值滚动借助semi-animation实现这些细节均可通过阅读 组件源码 与 Foundation 样式 进一步验证与复用。赞分享前端UI组件设计系统【免费下载链接】semi-designA modern, comprehensive, flexible design system and React UI library, AI-friendly built-in.Provide 3000 Design Tokens, easy to build your design system. Make Semi Design to Any Design.‍ Design to Code in one click项目地址https://gitcode.com/gh_mirrors/se/semi-design点击查看免费下载相关推荐Element 进度条组件 el-progress 完全指南从基础用法到源码原理Element 进度条组件 el progress 完全指南从基础用法到源码原理 本文基于 ElementA Vue.js 2.0 UI Toolkit f前端UI组件设计系统eCapture CPU 占用降低实战指南eBPF SSL/TLS 抓包性能调优三层拆解eCapture CPU 占用降低实战指南eBPF SSL/TLS 抓包性能调优三层拆解 eCapture 是一款基于 eBPF 的无证书 SSL/TLS 明前端UI组件设计系统Semi Design Badge 徽章组件完全指南从基础用法到源码级原理Semi Design Badge 徽章组件完全指南从基础用法到源码级原理 Badge 徽章组件是 Semi Design douyinfe/semi u前端UI组件设计系统上一篇如何快速修复损坏的MP4视频Untrunc完整使用指南下一篇终极跨平台表情解决方案如何用EmojiOne Color统一所有设备的表情显示创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
02
RELATED NEWS

相关资讯

更多网站建设与数字化升级内容

03
WHY YAOTU

想打造同款高转化官网?

懂行业、懂生意,从建站到增长一站式陪跑

◈

场景化定制

不做模板站,围绕你的业务场景量身设计,小众不撞款。

◐

营销型架构

以转化目标组织内容与路径,让官网真正带来询盘。

▲

全周期服务

设计、开发、运营、运维一体,上线只是开始。

免费获取你的建站方案

留下需求,专属顾问 24 小时内为你输出方案建议。