首页/新闻资讯/正文详情

Formily 单选框(Radio)组件完全指南:三种 Schema 写法与源码级原理剖析

发布时间:2026/9/23 16:21:33 来源:云帆数科 栏目:资讯中心
Formily 单选框(Radio)组件完全指南:三种 Schema 写法与源码级原理剖析
前端UI组件【免费下载链接】formily Cross Device High Performance Normal Form/Dynamic(JSON Schema) Form/Form Builder -- Support React/React Native/Vue 2/Vue 3项目地址https://gitcode.com/gh_mirrors/fo/formily点击查看免费下载本指南以 Formily 体系中formily/next的 Radio 组件文档为核心系统讲解如何在表单中实现单选功能。你将掌握 Markup Schema、JSON Schema、纯 JSX 三种声明方式下 Radio 的完整用法理解enum/dataSource选项数据的映射机制并深入connect/mapProps/mapReadPretty等源码层实现搞清楚单选值如何与表单模型双向同步、如何自动支持只读预览从而在实际项目中游刃有余地选用最合适的写法。一、组件定位Formily 中的单选组件Radio单选框是表单中最基础的选择类组件之一用于在若干互斥选项中仅选取一项。在 Formily 体系中各 UI 库适配层均提供了统一的Radio组件接口但它们底层渲染的具体控件不同formily/next基于阿里巴巴 Fusion Nextformily/antd基于 Ant Design 的Radio源码位于 packages/antd/src/radio/index.tsxformily/element基于 Element UI 的Radio/RadioButton源码位于 packages/element/src/radio/index.ts。本文以 packages/next/docs/components/Radio.md 文档为主展开其余实现作为对照参考。所有适配层都遵循同一个设计模式把第三方 UI 组件的 Props 通过connect桥接到 Formily 的字段模型上因此无论你使用哪套组件库写法与行为都高度一致。文档中组件被定义为 Single selection box单选选择框并声明了两种形态形态说明Radio单个单选项对应底层NextRadio/AntdRadio/ElRadioRadio.Group单选组对应底层NextRadio.Group/AntdRadio.Group/ElRadioGroup配合选项数据一次性渲染一组单选在实际业务中Radio.Group是更常用的形态因为它直接对接选项数据源与表单字段的值绑定。二、Markup Schema 写法声明式组件树Markup Schema 是 Formily 在 JSX 内部书写 JSON Schema 的 DSL 形式。它把 Schema 节点写成组件标签如SchemaField.Number /由编译器在运行时转换回标准 Schema 结构。文档中的示例完整代码如下源码见 packages/next/docs/components/Radio.mdimport React from react import { Radio, FormItem, FormButtonGroup, Submit } from formily/next import { createForm } from formily/core import { FormProvider, createSchemaField } from formily/react const SchemaField createSchemaField({ components: { Radio, FormItem, }, }) const form createForm() export default () ( FormProvider form{form} SchemaField SchemaField.Number nameradio titlesingle choice enum{[ { label: Option 1, value: 1, }, { label: Option 2, value: 2, }, ]} x-decoratorFormItem x-componentRadio.Group / /SchemaField FormButtonGroup Submit onSubmit{console.log}Submit/Submit /FormButtonGroup /FormProvider )关键点拆解注册组件createSchemaField({ components: { Radio, FormItem } })将Radio与FormItem注册进 SchemaField 的组件映射表这样x-componentRadio.Group和x-decoratorFormItem才能在运行时被正确解析。字段类型SchemaField.Number表明该字段的数据类型为number这也是单选值常用的类型选项 value 为 1、2。选项数据enum属性传入{ label, value }结构数组。在 Schema 编译阶段enum会被自动映射为字段的dataSource见后文「enum 与 dataSource 的映射原理」最终透传给Radio.Group渲染。装饰器与组件x-decoratorFormItem表示用 FormItem 包裹负责布局、标签、校验错误展示x-componentRadio.Group指定渲染单选组。提交Submit配合FormButtonGroup组成提交按钮onSubmit{console.log}会在提交时打印表单值此时form.values中的radio字段即为选中项的 value如1或2。三、JSON Schema 写法纯数据驱动JSON Schema 写法与 Markup Schema 在语义上完全等价只是把 Schema 从 JSX 中抽离为独立的 JSON 对象适合动态化、服务端下发的场景。文档示例见 packages/next/docs/components/Radio.mdimport React from react import { Radio, FormItem, FormButtonGroup, Submit } from formily/next import { createForm } from formily/core import { FormProvider, createSchemaField } from formily/react const SchemaField createSchemaField({ components: { Radio, FormItem, }, }) const form createForm() const schema { type: object, properties: { radio: { type: number, title: Single selection, enum: [ { label: Option 1, value: 1, }, { label: Option 2, value: 2, }, ], x-decorator: FormItem, x-component: Radio.Group, }, }, } export default () ( FormProvider form{form} SchemaField schema{schema} / FormButtonGroup Submit onSubmit{console.log}Submit/Submit /FormButtonGroup /FormProvider )与 Markup Schema 的差异仅在声明形式上Markup 写法用SchemaField.Number nameradio ... /JSON 写法用properties.radio { type: number, ... }。两者在运行时生成完全一致的字段模型。createSchemaField负责将 JSON Schema 编译为可被formily/react消费的内部结构enum同样会被转换为dataSource注入字段。四、纯 JSX 写法完全编程式控制如果不需要 Schema 的声明式能力例如选项数据来自运行时计算、或需要精细控制组件 Props可以直接使用Field组件以 JSX 方式编写。文档示例见 packages/next/docs/components/Radio.mdimport React from react import { Radio, FormItem, FormButtonGroup, Submit } from formily/next import { createForm } from formily/core import { FormProvider, Field } from formily/react const form createForm() export default () ( FormProvider form{form} Field nameradio titlesingle choice dataSource{[ { label: Option 1, value: 1, }, { label: Option 2, value: 2, }, ]} decorator{FormItem} component{Radio.Group} / FormButtonGroup Submit onSubmit{console.log}Submit/Submit /FormButtonGroup /FormProvider )注意纯 JSX 写法与 Schema 写法的对应关系Schema 属性JSX 属性说明enumdataSource选项数据源JSX 中直接使用字段模型的概念x-decoratorFormItemdecorator{FormItem}装饰器组件直接传组件引用而非字符串x-componentRadio.Groupcomponent{Radio.Group}渲染组件直接传组件引用Field组件把name、title、dataSource等属性写入字段模型并将Radio.Group作为实际渲染组件同时由FormItem装饰。三者中纯 JSX 写法最贴近传统 React 组件用法也是理解connect原理最直观的入口。五、enum 与 dataSource 的映射原理为什么 Schema 里写的是enum而 JSX 里写的是dataSource这是 Formily 刻意设计的标准 JSON Schema 关键字到内部状态模型的关键字映射。在 packages/json-schema/src/shared.ts 中定义了SchemaStateMapexport const SchemaStateMap { title: title, description: description, default: initialValue, enum: dataSource, // ← enum 映射为 dataSource readOnly: readOnly, writeOnly: editable, x-content: content, x-data: data, x-value: value, x-editable: editable, x-disabled: disabled, x-read-pretty: readPretty, x-read-only: readOnly, x-visible: visible, x-hidden: hidden, x-display: display, x-pattern: pattern, x-validator: validator, x-decorator: decoratorType, x-component: componentType, x-decorator-props: decoratorProps, x-component-props: componentProps, }Schema 编译时enum键会被翻译为字段状态中的dataSource。同文件中的patchStateFormSchemapackages/json-schema/src/shared.ts进一步处理了enum数组的标准化const isEnum key enum isArr(compiled) // ... isEnum ? createDataSource(compiled) : compiled而createDataSourcepackages/json-schema/src/shared.ts会把纯字符串/数字数组自动包装成{ label, value }结构export const createDataSource (source: any[]) { return toArr(source).map((item) { if (typeof item object) { return item } else { return { label: item, value: item, } } }) }这意味着你既可以写enum{[{ label: Option 1, value: 1 }]}这样的完整对象数组也可以简写为enum{[Option 1, Option 2]}后者会被自动补齐为{ label: Option 1, value: Option 1 }。这与formily/next组件层mapProps({ dataSource: true })的透传配合最终将标准化的选项数组送入 Fusion Next 的Radio.Group。六、组件源码解析connect 如何打通双向绑定Radio与Radio.Group的本质是formily/react的connect高阶组件包装。以 packages/next/src/radio/index.tsx 为例export const Radio: ComposedRadio connect( NextRadio, mapProps( { value: checked, }, mapSize ) ) Radio.Group connect( NextRadio.Group, mapProps( { dataSource: true, }, mapSize ), mapReadPretty(PreviewText.Select) )1. 单个 Radio 的 value → checked 映射mapProps({ value: checked })将 Formily 字段模型的value映射为 Fusion Next 单选项的checkedprop。单个Radio通常用于固定布尔型或独立开关场景如是否同意协议选中时checked true会通过onChange回写字段值。2. Radio.Group 的 dataSource 透传与尺寸联动mapProps({ dataSource: true })表示将字段的dataSource原样透传给Radio.Group。结合上文可知无论选项来自 Schema 的enum还是 JSX 的dataSource最终都会落在这个属性上。第二个映射mapSize来自 packages/next/src/builtins/mapSize.tsexport const mapSize (props: any) { const layout { ...useFormShallowLayout(), ...useFormLayout() } const takeSize () { return layout.size default ? medium : layout.size } return { ...props, size: props.size || takeSize(), } }mapSize从表单布局上下文FormLayout读取全局尺寸配置并注入组件使 Radio 能跟随表单统一调整大小small/medium/large无需在每个组件上手动声明。这正是 Formily 全局布局能力的体现详见 packages/next/src/form-layout/index.tsx。3. mapReadPretty自动只读预览mapReadPretty(PreviewText.Select)是单选组在只读态如详情页、表单回显下的关键实现。当字段处于readPretty模式时connect会自动用PreviewText.Select替换Radio.Group的渲染。PreviewText.Select的实现位于 packages/next/src/preview-text/index.tsxconst Select: React.FCReact.PropsWithChildrenSelectProps observer( (props) { const field useFieldField() // ... const dataSource: any[] field?.dataSource?.length ? field.dataSource : props?.dataSource?.length ? props.dataSource : [] const placeholder usePlaceholder() const getLabel (target: any) { return ( dataSource?.find((item) item.value target?.value)?.label || target.label || placeholder ) } // ... return div className{cls(prefixCls, props.className)}{getLabels()}/div } )它通过useField读取字段模型上的dataSource把当前选中的value反查为对应的label并以纯文本渲染无值时显示默认占位符N/A。这样在只读场景下单选值展示为可读文案而非被禁用的控件。占位符可通过PreviewText.Placeholder全局定制例如设置为暂无。4. Antd 版本对照packages/antd/src/radio/index.tsx 与 Next 版本高度一致差异仅在适配层细节export const Radio: ComposedRadio connect( AntdRadio, mapProps({ value: checked, }) ) Radio.__ANT_RADIO true Radio.Group connect( AntdRadio.Group, mapProps({ dataSource: options, // Antd 的选项属性名是 options }), mapReadPretty(PreviewText.Select) )Antd 版本额外设置了Radio.__ANT_RADIO true标记供内部逻辑识别组件来源dataSource: options将字段的dataSource映射为 Antd Radio.Group 的options属性而 Next 版本是dataSource: true原样透传——这是两套组件库 API 差异在适配层被抹平的直接证据只读预览同样使用PreviewText.Select对应实现在 packages/antd/src/preview-text/index.tsx额外支持fieldNames自定义label/value字段名。Element 版本Vue 场景见 packages/element/src/radio/index.ts它额外实现了options渲染逻辑与optionType: default | button的按钮形态切换RadioButton且选项值为label同样以mapProps({ dataSource: options })与mapReadPretty(PreviewText.Select)完成桥接。七、API 说明与扩展属性文档末尾给出的 API 说明为Reference https://fusion.design/pc/component/basic/radio即formily/next的Radio直接继承 Fusion Next Radio 的完整 API包括Radio.Group的dataSource、value、onChange、disabled、size等全部属性。Formily 适配层不改变底层组件的 API 语义只是把字段的值/数据源/状态与组件对接因此底层组件的任何能力如Radio.Group的方向布局、按钮样式等均可直接使用。在此基础上Formily 还叠加了下列由适配层提供的增强能力能力实现机制说明字段值双向同步connectmapProps({ value: checked })选中状态与字段模型value实时同步选项数据自动注入mapProps({ dataSource: true / options })从字段dataSource映射到底层组件的选项属性尺寸联动mapSize仅 Next跟随FormLayout全局尺寸自动调整只读预览mapReadPretty(PreviewText.Select)readPretty模式下渲染为纯文本 label校验与错误展示x-decoratorFormItem的字段联动单选必选校验通过 FormItem 呈现必选校验示例结合FormItem装饰器只需为字段声明required即可启用单选必选校验SchemaField.Number nameradio titlesingle choice required enum{[ { label: Option 1, value: 1 }, { label: Option 2, value: 2 }, ]} x-decoratorFormItem x-componentRadio.Group /未选择任何选项时提交FormItem 会展示该字段必填的校验提示Submit也不会触发onSubmit回调。八、三种写法的选型建议写法适用场景优势注意点Markup Schema常规表单开发希望 Schema 与 JSX 共处类型友好、IDE 提示好、可读性高需createSchemaField注册组件JSON Schema动态表单、服务端下发 Schema、低代码平台纯数据可序列化、易于持久化与远程传输Schema 需自行维护与校验纯 JSX逻辑复杂、选项运行时计算、精细控制组件无 Schema 心智负担、最接近原生 React 用法数据源需显式传dataSource三者最终都会汇入formily/core的字段模型通过FormProvider共享同一个form实例因此校验、联动、提交等能力完全一致可以在同一表单内混用。九、小结本文围绕 packages/next/docs/components/Radio.md 的三个完整示例完整呈现了formily/next中 Radio 单选框的三种声明方式Markup SchemaSchemaField.Number x-componentRadio.Group enum{...} /JSON Schemaproperties.radio { type: number, enum: [...], x-component: Radio.Group }纯 JSXField component{Radio.Group} dataSource{...} /。并从源码层验证了三个关键机制enum → dataSource的标准 JSON Schema 关键字映射packages/json-schema/src/shared.ts、connect/mapProps/mapSize的双向绑定与尺寸联动packages/next/src/radio/index.tsx、packages/next/src/builtins/mapSize.ts、以及mapReadPretty(PreviewText.Select)的只读文本预览packages/next/src/preview-text/index.tsx。这些机制在formily/antd、formily/element中同样成立只是底层映射的组件属性名略有差异。掌握了 Radio 的用法也就掌握了 Formily 中所有选项型组件Select、Checkbox、Cascader 等的通用接入范式——它们共享同一套dataSource数据契约与connect桥接模型可以举一反三。赞分享前端UI组件【免费下载链接】formily Cross Device High Performance Normal Form/Dynamic(JSON Schema) Form/Form Builder -- Support React/React Native/Vue 2/Vue 3项目地址https://gitcode.com/gh_mirrors/fo/formily点击查看免费下载相关推荐Formily Next 的 Radio 单选框组件三种 Schema 写法与源码级封装解析Formily Next 的 Radio 单选框组件三种 Schema 写法与源码级封装解析 本文基于 Formily 2.x 的 formily/next前端UI组件Formily Next 复选框组件 Checkbox 完全使用指南Markup Schema / JSON Schema / Pure JSX 三种写法与源码原理Formily Next 复选框组件 Checkbox 完全使用指南Markup Schema / JSON Schema / Pure JSX 三种写法与源前端UI组件Formily 复选框组件 Checkbox 完全指南Markup Schema / JSON Schema / JSX 三种用法与源码级桥接原理Formily 复选框组件 Checkbox 完全指南Markup Schema / JSON Schema / JSX 三种用法与源码级桥接原理 本文围绕前端UI组件创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关推荐

壶之贵人高频面试题解析:3招搞定底层原理
壶之贵人高频面试题解析:3招搞定底层原理

壶之贵人高频面试题解析:3招搞定底层原理 看了一堆教程还是不会写项目?别慌,这不是你的错。很多开发者卡在“懂原理”和“会落地”之间的鸿沟,尤其是面对 高频面试题… · 2026/9/23 16:21:27

DeepSeek微调实战:用LoRA与风格迁移生成影视剧本
DeepSeek微调实战:用LoRA与风格迁移生成影视剧本

简介:《影视剧本创作:DeepSeek行业语料微调与风格迁移技术》是一份面向影视编剧、AI应用开发者与内容创作者的实操型技术文档,旨在借助DeepSeek大模型解决传统剧本创作中效率偏低、题材同质化、市场适应性弱等痛点,适合希望掌握专… · 2026/9/23 16:21:20

RT-Thread VANGOV85XXP-EVAL 板级支持包详解:从编译烧写到驱动移植
RT-Thread VANGOV85XXP-EVAL 板级支持包详解:从编译烧写到驱动移植

RT-Thread VANGOV85XXP-EVAL 板级支持包详解:从编译烧写到驱动移植 【免费下载链接】rt-thread RT-Thread is an open source IoT Real-Time Operating System (RTOS). https://rt-thread.github.io/rt-thread/ 项目地址: https://gitcode.com/gh_mirrors/rt/rt-t… · 2026/9/23 16:21:14

800V直流供电重塑智算中心配电架构的关键技术与实践
800V直流供电重塑智算中心配电架构的关键技术与实践

简介:《基于800V直流供电的智算中心配电系统设计》是一份聚焦AI算力爆发背景下数据中心供电变革的技术资料。它围绕800V高压直流(HVDC)供电,剖析传统交流系统效率低、空间占用大、灰白区失衡及新能源接入难等痛点,梳理… · 2026/9/23 17:07:21

2026最新仇之杀实战:搞定版本升级API全变乱的5个关键步骤
2026最新仇之杀实战:搞定版本升级API全变乱的5个关键步骤

2026最新仇之杀实战:搞定版本升级API全变乱的5个关键步骤 刚接手市政公用工程移动端项目时,我盯着屏幕上红色的报错信息愣了半秒。上周还跑通得飞起的接口,今天突然全线404,后端同事轻飘飘一句“库升级了,API全变了”,我手里那份写着【仇… · 2026/9/23 17:07:15

限速坡道地铁节能策略:强化学习Q-learning与DQN代码包解析
限速坡道地铁节能策略:强化学习Q-learning与DQN代码包解析

简介:这是一份面向地铁列车运行控制与能耗管理场景的强化学习项目,核心是基于Q-learning算法优化列车在限速坡道条件下的牵引与制动策略,以实现能耗最小化。代码工程围绕环境建模、控制模型与训练评估展开,适合轨道交通自动化、计… · 2026/9/23 17:07:15

OpenClaw 彻底卸载教程:Windows/macOS/Linux 全平台清理与 TaoToken 配置残留排查
OpenClaw 彻底卸载教程:Windows/macOS/Linux 全平台清理与 TaoToken 配置残留排查

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/23 17:07:14

PI Agent SDK嵌入式集成指南:从初始化到工具调用的完整实践
PI Agent SDK嵌入式集成指南:从初始化到工具调用的完整实践

做LLM Agent的项目,最烦的就是每做一个应用都要从零搭一遍对话链路、记忆管理、工具调用这些基础设施。前面二十多期PI系列的文章里,我们已经把PI Agent的安装、配置、桌面端玩法聊得差不多了,这次换个方向,聊一聊怎么把PI Agent用… · 2026/9/23 17:07:14

EMQX 会话上限超限后的重连恢复机制解析——基于 v5.8.5 行为修复 14654
EMQX 会话上限超限后的重连恢复机制解析——基于 v5.8.5 行为修复 14654

EMQX 会话上限超限后的重连恢复机制解析——基于 v5.8.5 行为修复 #14654 【免费下载链接】emqx The most scalable and reliable MQTT broker for AI, IoT, IIoT and connected vehicles 项目地址: https://gitcode.com/gh_mirrors/em/emqx 导读 本文围绕 EMQX 仓库变… · 2026/9/23 17:07:07

3招搞定手机怎么下载微信面试难题实战项目解析
3招搞定手机怎么下载微信面试难题实战项目解析

3招搞定手机怎么下载微信面试难题实战项目解析 面试被问“手机怎么下载微信”背后的原理,90%的人答不上来。别笑,这看似弱智的问题,实则是考察你对移动应用分发机制、安全校验及网络协议理解的试金石。我带过不少校招新人,他们背了八股文,却连一个A… · 2026/9/23 0:00:03

你有新短消息请注意查收:3个新手避坑指南搞定消息系统选型
你有新短消息请注意查收:3个新手避坑指南搞定消息系统选型

你有新短消息请注意查收:3个新手避坑指南搞定消息系统选型 面试被问“高并发下如何保证消息不丢失”,你张口就是“用Redis”,结果面试官追问“如果Redis宕机了怎么办”,你瞬间卡壳。这种场景太常见了,很多新手在背八股文时,只记住了技术名词… · 2026/9/23 0:00:29

Win7无线热点配置工具源码解析:解决API失效的3个实战技巧
Win7无线热点配置工具源码解析:解决API失效的3个实战技巧

Win7无线热点配置工具源码解析:解决API失效的3个实战技巧 Win7无线热点配置工具在Win10/11上跑不动?不是你的问题,是版本升级后 API 全变了。很多老项目里的 netsh wlan… · 2026/9/23 0:00:36

了解更多?预约专属演示

我们的顾问将为您一对一讲解产品与方案

企业微信二维码