amis 按钮点选控件 button-group-select:用 JSON 配置实现按钮式表单选择器
2026/9/13 18:09:19 网站建设 项目流程

amis 按钮点选控件 button-group-select:用 JSON 配置实现按钮式表单选择器

【免费下载链接】amis前端低代码框架,通过 JSON 配置就能生成各种页面。项目地址: https://gitcode.com/GitHub_Trending/am/amis

在 amis 低代码框架中,button-group-select是一种"按钮集合当 select 点选"的表单项控件:它以按钮组的视觉形态呈现一组选项,用户点击按钮即完成选择,适合作为性别、状态、类型等少量枚举值的快速选择器。本文基于官方文档 button-group-select 组件文档 与仓库源码,完整讲解其基本用法、垂直/平铺布局、按钮主题样式、角标配置、选项与值格式化参数,以及change事件与clear/reset/reload/setValue四类特性动作,并结合 组件实现文件 与 选项控件 HOC 说明其底层调用链。读完后你可以直接用 JSON Schema 搭建按钮点选表单项,并掌握与数据域联动、跨组件控制的完整方案。

基本用法

formbody中放置一个type: "button-group-select"的表单项,通过options声明选项集合,即可得到一个可点选的按钮组。选中值会写入表单数据域的name字段(本例为type),随表单提交到api指定的接口:

{ "type": "form", "api": "/api/mock2/form/saveForm", "debug": true, "body": [ { "type": "button-group-select", "label": "选项", "name": "type", "options": [ {"label": "Option A", "value": "a"}, {"label": "Option B", "value": "b"}, {"label": "Option C", "value": "c"} ] } ] }

从源码看,该控件的渲染器注册在 ButtonGroupSelect.tsx,使用@OptionsControl装饰器以type: 'button-group-select'注册,并声明了sizeMutable: false(尺寸不可被表单联动改变)与strictMode: false(不启用严格更新模式,选项/数据变化时允许重渲染)。组件本体继承自OptionsControlProps,即所有"列表选择类控件"(Select、Radios、Checkboxes 等)共用的父类接口,因此它天然获得选项加载、多选、值格式化等一整套能力。

垂直模式

配置"vertical": true后,按钮组由横向排列改为纵向排列,适合选项文字较长、标签较多、需要逐行点选的场景:

{ "type": "form", "api": "/api/mock2/form/saveForm", "body": [ { "type": "button-group-select", "label": "选项", "name": "type", "vertical": true, "options": [ {"label": "Option A", "value": "a"}, {"label": "Option B", "value": "b"}, {"label": "Option C", "value": "c"} ] } ] }

实现上,render方法会把vertical转成根节点样式类ButtonGroup--vertical(见 ButtonGroupSelect.tsx 的 render),对应样式定义在 amis-ui 按钮组 SCSS 中;对应的单元测试 buttonGroupSelect.test.tsx 通过断言.cxd-ButtonGroup.cxd-ButtonGroup--vertical存在来验证该行为。

平铺模式

配置"tiled": true实现平铺模式,按钮按网格均匀铺满容器宽度,视觉上更接近"卡片点选",适合移动端或需要大点击热区的场景:

{ "type": "form", "api": "/api/mock2/form/saveForm", "body": [ { "type": "button-group-select", "label": "选项", "name": "type", "tiled": true, "options": [ {"label": "Option A", "value": "a"}, {"label": "Option B", "value": "b"}, {"label": "Option C", "value": "c"} ] } ] }

与垂直模式同理,tiled会映射到样式类ButtonGroup--tiled(SCSS 中的平铺样式),单元测试中同样以.cxd-ButtonGroup--tiled的存在性作为验证依据(测试代码)。

按钮主题样式:btnLevel 与 btnActiveLevel

配置btnLevel统一设置所有按钮的主题样式,配置btnActiveLevel为按钮设置激活态(选中态)的主题样式。注意:buttonsoptions中每个选项自己的level属性优先级高于btnLevel

{ "type": "form", "api": "/api/mock2/form/saveForm", "debug": true, "body": [ { "type": "button-group-select", "label": "选项", "name": "type", "btnLevel": "light", "btnActiveLevel": "warning", "options": [ {"label": "Option A", "value": "a"}, {"label": "Option B", "value": "b"}, {"label": "Option C", "value": "c", "level": "primary"} ] } ] }

btnLevelbtnActiveLevel的取值范围为'link' | 'primary' | 'secondary' | 'info' | 'success' | 'warning' | 'danger' | 'light' | 'dark' | 'default',文档标注的默认值均为"default"

源码中的优先级逻辑非常直白,选中按钮的 level 按"激活样式 > 选项自身样式 > 整体默认样式"计算(level 计算表达式):

level: (active ? btnActiveLevel : '') || option.level || btnLevel

即:按钮处于选中态时优先使用btnActiveLevel;未选中时先取选项自己的level,再回退到btnLevel。另外,若配置了旧版属性btnClassName/btnActiveClassName,源码会通过getLevelFromClassName解析出 level 覆盖btnLevel/btnActiveLevel(className 解析逻辑),这两个旧属性在新版中已被标记为废弃。组件类型定义 中也明确注释了@deprecated 建议用btnLevel

单测 btnActiveLevel 用例 精确验证了这套优先级:在btnLevel: 'light'btnActiveLevel: 'warning'的配置下,选中项(value: 'a')最终呈现cxd-Button--warning,未选中但带level: 'primary'的项呈现cxd-Button--primary,其余项回退为cxd-Button--light

支持角标

按钮可支持角标,在options的单个选项中配置badge即可。badge支持mode: "text"(数字/文字角标)与mode: "ribbon"(缎带角标)等形态,完整属性见 badge 组件文档:

{ "type": "form", "api": "/api/mock2/form/saveForm", "debug": true, "body": [ { "type": "button-group-select", "label": "选项", "name": "type", "options": [ {"label": "Option A", "value": "a"}, { "label": "Option B", "value": "b", "badge": {"mode": "text", "text": 15} }, { "label": "Option C", "value": "c", "badge": {"mode": "ribbon", "text": "HOT"} } ] } ] }

从源码看,角标配置还具备"控件级兜底 + 选项级覆盖"的合并能力(getBadgeConfig 方法):如果控件整体配置了badge,则每个选项的badge(对象会展开覆盖兜底配置,字符串/数字会填充到text字段)优先生效;未配置控件级badge时直接使用选项自身配置。该能力自2.8.1版本引入。

属性表

当做选择器表单项使用时,除了支持 普通表单项属性表 中的配置以外,还支持下面一些配置:

属性名类型默认值说明版本
typestring"button-group-select"指定为 button-group-select 渲染器
verticalbooleanfalse是否使用垂直模式
tiledbooleanfalse是否使用平铺模式
btnLevel'link' \| 'primary' \| 'secondary' \| 'info' \| 'success' \| 'warning' \| 'danger' \| 'light' \| 'dark' \| 'default'"default"按钮样式
btnActiveLevel'link' \| 'primary' \| 'secondary' \| 'info' \| 'success' \| 'warning' \| 'danger' \| 'light' \| 'dark' \| 'default'"default"选中按钮样式
optionsArray<object>Array<string>静态选项组
option.badgeobject角标2.8.1
sourcestring或 API动态选项组
multiplebooleanfalse多选
labelFieldstring"label"选项标签字段
valueFieldstring"value"选项值字段
joinValuesbooleantrue拼接值
extractValuebooleanfalse提取值
autoFillobject自动填充

补充几点与源码互相印证的细节:

  • source支持字符串 URL、API 对象,也支持形如"${xxx}"的纯变量表达式从数据域取选项;labelField/valueField用于指定选项中"标签"和"值"的字段名(源码渲染按钮文本时即为option[labelField || 'label'],见 渲染逻辑)。
  • 多选模式下的值格式化由joinValues(默认true,用delimiter把多个值拼成字符串)与extractValue(默认false,开启后值封装为数组)共同决定,实现位于 OptionsControlBase 的 formatValueArray / toggleValue 中。单选模式下clearable(该控件默认false,见 defaultProps)允许再次点击已选按钮取消选择。
  • optionsbuttons均为空,控件会渲染占位文本(placeholder 分支),配合placeholder属性显示提示文案。

事件表

当前组件会对外派发以下事件,可以通过onEvent来监听这些事件,并通过actions来配置执行的动作,在actions中可以通过${事件参数名}${event.data.[事件参数名]}来获取事件产生的数据,详细请查看 事件动作。

[name]表示当前组件绑定的名称,即name属性,如果没有配置name属性,则通过value取值。

事件名称事件参数说明
change[name]: string组件的值选中值变化时触发

从源码调用链看,按钮点击触发handleToggle→ 父层 OptionsControlBase.handleToggle 计算新值后,先dispatchOptionEvent('change', {value: newValue})派发change事件(支持在 actions 中返回prevented阻塞取值),未被阻塞才调用onChange写回表单值。也就是说,change事件可以在其他组件的联动动作中被拦截。

change

{ "type": "form", "debug": true, "body": [ { "type": "button-group-select", "label": "选项", "name": "type", "options": [ {"label": "Option A", "value": "a"}, {"label": "Option B", "value": "b"}, {"label": "Option C", "value": "c"} ], "onEvent": { "change": { "actions": [ { "actionType": "toast", "args": { "msg": "${event.data.value|json}" } } ] } } } ] }

动作表

当前组件对外暴露以下特性动作,其他组件可以通过指定actionType: 动作名称componentId: 该组件id来触发这些动作,动作配置可以通过args: {动作配置项名称: xxx}来配置具体的参数,详细请查看 事件动作。

动作名称动作配置说明
clear-清空
reset-将值重置为初始值。6.3.0 及以下版本为resetValue
reload-重新加载,调用source,刷新数据域数据刷新(重新加载)
setValuevalue: string更新的值更新数据

其中clearreset的具体实现在 ButtonGroupControl.doAction 中:clear直接调用onChange('')清空;reset则优先取表单初始值(formStore.pristine)中该name对应的值,取不到再回退到resetValue,最后兜底为空字符串。

clear

{ "type": "form", "debug": true, "body": [ { "type": "button-group-select", "label": "选项", "name": "type", "id": "clear_type", "options": [ {"label": "Option A", "value": "a"}, {"label": "Option B", "value": "b"}, {"label": "Option C", "value": "c"} ], "value": "b" }, { "type": "button", "label": "清空", "onEvent": { "click": { "actions": [ { "actionType": "clear", "componentId": "clear_type" } ] } } } ] }

reset

如果配置了resetValue,则重置时使用resetValue的值,否则使用初始值。

{ "type": "form", "debug": true, "data": { "abc": { "type": "c" } }, "body": [ { "type": "button-group-select", "label": "选项", "name": "type", "id": "reset_type", "options": [ {"label": "Option A", "value": "a"}, {"label": "Option B", "value": "b"}, {"label": "Option C", "value": "c"} ], "value": "b" }, { "type": "button", "label": "重置", "onEvent": { "click": { "actions": [ { "actionType": "reset", "componentId": "reset_type" } ] } } } ] }

reload

只有选择器模式支持,即配置source,用于重新加载选择器的数据源。组件侧的reload方法会透传给 HOC 提供的reloadOptions(reload 透传),底层 reloadOptions 实现 会区分"纯变量表达式 source(重新从数据域取值)"与"接口 source(重新请求)"两种路径。

{ "type": "form", "debug": true, "body": [ { "type": "button-group-select", "label": "选项", "name": "type", "id": "reload_type", "source": "/api/mock2/form/getOptions?waitSeconds=1" }, { "type": "button", "label": "重新加载", "onEvent": { "click": { "actions": [ { "actionType": "reload", "componentId": "reload_type" } ] } } } ] }

setValue

{ "type": "form", "debug": true, "body": [ { "type": "button-group-select", "label": "选项", "name": "type", "id": "setvalue_type", "options": [ {"label": "Option A", "value": "a"}, {"label": "Option B", "value": "b"}, {"label": "Option C", "value": "c"} ], "value": "b" }, { "type": "button", "label": "赋值", "onEvent": { "click": { "actions": [ { "actionType": "setValue", "componentId": "setvalue_type", "args": { "value": "c" } } ] } } } ] }

可视化编辑与相关资源

除 JSON 配置外,amis 可视化编辑器也内置了该组件的插件:编辑器插件定义 将组件命名为"按钮点选",默认脚手架即一份带optionsbutton-group-selectSchema,编辑面板中可直接维护选项、btnLevel、事件与动作,其事件元数据同样声明了change事件的value参数结构。相关可深入阅读的仓库文件:

  • 渲染器实现:packages/amis/src/renderers/Form/ButtonGroupSelect.tsx
  • 选项控件通用 HOC(source 加载、多选、值格式化):packages/amis-core/src/renderers/Options.tsx
  • 按钮组基础类型定义(btnLevel/vertical/tiled 等):packages/amis/src/renderers/ButtonGroup.tsx
  • 单元测试:packages/amis/tests/renderers/Form/buttonGroupSelect.test.tsx
  • 按钮组样式:packages/amis-ui/scss/components/_button-group.scss

【免费下载链接】amis前端低代码框架,通过 JSON 配置就能生成各种页面。项目地址: https://gitcode.com/GitHub_Trending/am/amis

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询