amis Progress 进度条组件完全指南:从颜色映射到事件动作的 JSON 配置实战
【免费下载链接】amis前端低代码框架,通过 JSON 配置就能生成各种页面。项目地址: https://gitcode.com/GitHub_Trending/am/amis
进度条(Progress)是 amis 前端低代码框架内置的展示型组件,通过一段 JSON Schema 即可渲染条形、圆形、仪表盘三种形态的进度效果,并支持颜色映射、阈值刻度、条纹动画、字段联动与事件动作等能力。本文以官方文档 progress.md 为主体,结合 Progress 渲染器源码、amis-ui 底层实现 与 单元测试,完整讲解该组件的全部配置项、底层取值与配色原理,以及作为 Field 嵌入 Table、Card、表单静态展示的实战用法,读完即可在页面 JSON 中直接落地使用。
一、基本用法
progress组件最核心的属性只有两个:type: "progress"与value(进度值)。一个最小可用的页面配置如下:
{ "type": "page", "body": { "type": "progress", "value": 60 } }在 amis 架构中,该组件由两层协作完成:
- 渲染器层:
packages/amis/src/renderers/Progress.tsx中的ProgressField通过@Renderer({type: 'progress'})注册为 amis 渲染器,负责取值、模板过滤、状态维护与动作分发; - 表现层:底层复用
amis-ui的Progress组件(packages/amis-ui/src/components/Progress.tsx),负责条形/环形/仪表盘的实际绘制。
取值逻辑(见 Progress.tsx)会先走getPropValue读取,若拿到的是模板字符串再经filter按当前数据域渲染,最终把形如"60"的字符串parseFloat为数字。因此value既可以直接写数字,也可以写"${xxx}"之类的模板表达式,动态跟随数据变化。
二、颜色映射 map:三种配置形态与底层分段原理
map属性用于按进度值切换进度条颜色,官方文档给出三种写法,amis-ui中用联合类型ColorMapType = Array<string> | Array<ColorProps> | string约束(见 Progress.tsx)。
1. 单个颜色字符串
配置为单一颜色值(如#F96D3E)时,整个进度条固定为该颜色:
{ "type": "page", "body": { "type": "progress", "value": 40, "map": "#F96D3E" } }2. 字符串数组:按等分区间切换 CSS 类
默认的map配置为:
['bg-danger', 'bg-warning', 'bg-info', 'bg-success', 'bg-success']它意味着将进度条平均分成 5 份:前 20% 添加bg-dangerCSS 类名,20%~40% 添加bg-warning,40%~60% 添加bg-info,60%~80% 与 80%~100% 均添加bg-success。该规则在底层getColorArray(Progress.tsx)中实现:span = 100 / color.length,第index个元素的分段阈值为(index + 1) * span,即 20%、40%、60%、80%、100%。
因此,配置两个元素['bg-danger', 'bg-success']时即按 50% 为界切换,完全由数组长度决定分段粒度。
{ "type": "page", "body": { "type": "progress", "value": 60, "map": ["bg-danger", "bg-success"] } }说明:默认值在 ProgressField.defaultProps 中定义。当完全不配置
map时,底层getCurrentColor会回退到bg-primary(见 Progress.tsx)。
3. 对象数组:精确控制每个区间
当需要精确控制"多少进度显示什么颜色"时,使用{value, color}对象数组。例如:
{ "type": "progress", "value": 20, "map": [{ "value": 30, "color": "#007bff" }, { "value": 60, "color": "#fad733" }], "mode": "circle" }语义为:value小于等于 30 的区间显示#007bff,大于 30 则显示#fad733。底层getLevelColor(Progress.tsx)会先把数组按value升序排序,然后返回第一个阈值大于等于当前进度的颜色;若当前进度超过所有阈值,则取数组中最后一个颜色。
源码对颜色字符串有个关键判断:isColorClass = /bg-/.test(bgColor)(见 Progress.tsx)。命中bg-*时按 CSS 类名挂载(条形走bar的 className,环形走rc-progress的prefixCls,对应_progress.scss中的.bg-warning-circle-path等 stroke 规则);否则视为真实颜色值,直接写入backgroundColor(条形)或strokeColor(环形)。单元测试 Progress.test.tsx 完整验证了两种写法的渲染结果。
三、阈值(刻度)threshold 与 showThresholdText
threshold用于在条形进度条上绘制刻度线,帮助用户直观判断"当前进度处于哪个节点"。配置格式为单个对象或对象数组,其中value、color均支持模板:
{ "type": "page", "body": { "type": "progress", "value": 60, "threshold": [ { "value": "30%", "color": "red" }, { "value": "90%", "color": "blue" } ], "showThresholdText": true } }从实现看,amis 渲染器在传入底层前会先对阈值做模板解析(见 Progress.tsx):value与color为字符串时经filter按当前数据域渲染,从而支持"${xxx}%"这种动态刻度。底层渲染时(Progress.tsx)将value统一parseFloat后拼上%,以绝对定位的竖线(border-left)落在进度条相应位置;刻度线颜色默认取var(--text-color),showThresholdText: true时在刻度线下方(bottom: -20px)展示刻度文本,相关样式见 _progress.scss。
四、用作 Field:Table 列、List/Card 内容与表单静态展示
Progress 不只能独立渲染,还可以作为字段组件嵌入数据展示容器:用于 Table 的列配置 Column、List 的内容、Card 卡片的内容,以及表单的静态展示中。此时只需设置name属性,组件即会从当前数据域中映射同名变量的值。
Table 中的列类型
{ "type": "table", "data": { "items": [ { "id": "1", "progress": 20 }, { "id": "2", "progress": 40 }, { "id": "3", "progress": 60 } ] }, "columns": [ { "name": "id", "label": "Id" }, { "name": "progress", "label": "进度", "type": "progress" } ] }List 的内容、Card 卡片的内容配置方式与上述 Table 列完全一致,即{ "name": "progress", "type": "progress" }。
Form 中静态展示
在表单内做只读展示时,使用static-progress类型:
{ "type": "form", "data": { "progress": 60 }, "body": [ { "type": "static-progress", "name": "progress", "label": "进度" } ] }组件之所以能同时以progress与static-progress两种形态工作,依赖 amis 的兼容层映射(见 compat.ts),其中'progress': 'static-progress'将普通展示组件自动转换为表单静态组件。同时,amis 渲染器会监听name、value、data、defaultValue四个键的变化并刷新值(COMPARE_KEYS,见 Progress.tsx),因此数据更新后进度会随之联动。
五、显示背景间隔 stripe 与动画 animate
stripe: true让条形进度条显示斜向条纹背景,animate: true则启用动态效果。两者可以独立使用,也可以组合出"条纹滚动"的效果。
{ "type": "page", "body": [ { "type": "progress", "animate": true, "value": 60 }, { "type": "divider" }, { "type": "progress", "animate": true, "value": 60, "stripe": true } ] }注意:动画只在条形进度条(mode为line)下生效。从底层实现看(Progress.tsx),stripe/animate只作用于 line 分支的bar节点,环形与仪表盘走rc-progress的Circle分支,不参与这两项。样式层面对应三类修饰类(见 _progress.scss):
.Progress-line-bar--stripe:45 度线性渐变斜纹;.Progress-line-bar--animate:progress-bar-active动画(2.4s 流光扫过效果,cubic-bezier 缓动,无限循环);.Progress-line-bar--stripe-animate:progress-bar-stripes动画(1s 线性平移,让斜纹滚动起来)。
因此 "条纹 + 动画" 会得到斜纹持续滚动的经典加载态效果,而单独animate则是高光扫过的流光效果。
六、圆形进度条与仪表盘进度条
圆形进度条
通过mode: "circle"切换为环形:
{ "type": "page", "body": { "type": "progress", "value": 60, "mode": "circle" } }仪表盘进度条
mode: "dashboard"渲染为缺口的仪表盘形态,可通过gapDegree设置缺口角度、gapPosition设置缺口位置:
{ "type": "page", "body": { "type": "progress", "value": 60, "mode": "dashboard", "gapDegree": 22, "gapPosition": "bottom" } }底层实现(Progress.tsx)对两者统一处理:
- 环形/仪表盘基于
rc-progress的Circle组件绘制,percent即进度值; gapPosition缺省时,仪表盘默认取bottom,普通圆形默认取top;gapDegree缺省时仪表盘默认取75,且可传0显式闭合;- 容器尺寸由
strokeWidth决定:宽高均为strokeWidth * 10(px),未配置时线宽取8。
七、设置线条宽度 strokeWidth
strokeWidth同时控制进度条线宽与(环形/仪表盘模式的)整体尺寸。条形模式直接把它作为进度条高度(barStyle.height),环形模式则作为描边宽度并参与容器尺寸计算。官方属性表标注:line类型默认10,circle、dashboard类型默认6;需要指出的是,底层 UI 组件在未传值时实际按strokeWidth || 8兜底,以实际渲染为准。
{ "type": "page", "body": [ { "type": "progress", "value": 60, "mode": "line", "strokeWidth": 4 }, { "type": "progress", "value": 60, "mode": "line", "strokeWidth": 8 }, { "type": "progress", "value": 60, "mode": "line", "strokeWidth": 12 }, { "type": "progress", "value": 60, "mode": "dashboard", "strokeWidth": 4 }, { "type": "progress", "value": 60, "mode": "dashboard", "strokeWidth": 8 }, { "type": "progress", "value": 60, "mode": "dashboard", "strokeWidth": 12 } ] }八、自定义格式输出内容 valueTpl
默认情况下,进度文本展示为60%(由默认值${value}%决定)。通过valueTpl可自定义文本格式,模板语法与 amis 通用的模板渲染一致,内置变量value即当前进度值:
{ "type": "page", "body": { "type": "progress", "mode": "circle", "value": 60, "valueTpl": "${value}个" } }实现上(Progress.tsx),format方法用createObject(data, {value})把当前值注入数据域,再以valueTpl作为模板渲染,因此valueTpl里还可以引用页面上的其他变量,例如"${value}/${total}"。另外,若设showLabel: false,可完全隐藏进度文本(底层getLabel返回 null);当值为非数字(如未取到数据)时,条形模式会展示占位文本placeholder(默认-),环形模式则不渲染内容,相关逻辑见 Progress.tsx。
九、属性表
| 属性名 | 类型 | 默认值 | 说明 |
|---|---|---|---|
| type | string | 如果在 Form 中用作静态展示,为"static-progress" | |
| mode | string | line | 进度「条」的类型,可选line circle dashboard |
| className | string | 外层 CSS 类名 | |
| value | 模板 | 进度值 | |
| placeholder | string | - | 占位文本 |
| showLabel | boolean | true | 是否展示进度文本 |
| stripe | boolean | false | 背景是否显示条纹 |
| animate | boolean | false | type 为 line,可支持动画 |
| map | string \| Array<string> \| Array<{value:number, color:string}> | ['bg-danger', 'bg-warning', 'bg-info', 'bg-success', 'bg-success'] | 进度颜色映射 |
| threshold | {value:模板, color?:模板} | Array<{value:模板, color?:模板}> | - | 阈值(刻度) |
| showThresholdText | boolean | false | 是否显示阈值(刻度)数值 |
| valueTpl | string | ${value}% | 自定义格式化内容 |
| strokeWidth | number | line 类型为10,circle、dashboard 类型为6 | 进度条线宽度 |
| gapDegree | number | 75 | 仪表盘缺角角度,可取值 0 ~ 295 |
| gapPosition | string | bottom | 仪表盘进度条缺口位置,可选top bottom left right |
十、事件动作:reset 与 setValue
Progress 对外暴露两个特性动作,其他组件可通过actionType: 动作名称、componentId: 该组件 id触发,并通过args传参。完整的事件动作机制见事件动作文档。
| 动作名称 | 动作配置 | 说明 |
|---|---|---|
| reset | - | 将值重置为 0 |
| setValue | value: string|number更新的值 | 更新数据 |
这两个动作在 ProgressFieldRenderer 中实现:doAction捕获reset并将内部value置 0;setData负责数值类型转换后更新状态,配合渲染器在ScopedContext中的注册/注销机制,使组件可被componentId精准寻址。
reset 示例
{ "type": "page", "body": [ { "type": "progress", "name": "progress", "id": "progress", "value": 67 }, { "type": "button", "label": "重置值", "onEvent": { "click": { "actions": [ { "actionType": "reset", "componentId": "progress" } ] } } } ] }setValue 示例
{ "type": "page", "body": [ { "type": "progress", "name": "progress", "id": "progress", "value": 67 }, { "type": "button", "label": "设置值", "onEvent": { "click": { "actions": [ { "actionType": "setValue", "componentId": "progress", "args": { "value": 20 } } ] } } } ] }小结
Progress 组件的能力清单可以概括为:三种形态(line / circle / dashboard)、三类配色映射(单色 / 等分数组 / 对象区间)、两套刻度与动效(threshold 阈值、stripe 条纹 + animate 动画)、一个模板出口(valueTpl)与两个动作入口(reset / setValue)。从源码看,取值、模板解析、颜色分段、动画类切换各司其职,单元测试 Progress.test.tsx 对上述能力逐项覆盖。在实际项目中,进度条常与 Table、Card、List 等数据展示组件组合,实现"数据即进度"的动态展示效果。
【免费下载链接】amis前端低代码框架,通过 JSON 配置就能生成各种页面。项目地址: https://gitcode.com/GitHub_Trending/am/amis
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考