element-react Radio 单选框组件详解:受控选中、Group 聚合与 Button 样式的源码级解析
前端UI组件设计系统【免费下载链接】element-reactElement UI项目地址https://gitcode.com/gh_mirrors/el/element-react点击查看免费下载本篇技术文章围绕 element-reactElement UI for React当前仓库版本 1.4.34的 Radio 单选框组件展开从单选的受控写法、禁用状态到Radio.Group单选框组与Radio.Button按钮样式完整继承官方文档的全部示例与 API 参数表并深入src/radio/源码解析选中判定、事件冒泡链路与 Context 通信的底层实现帮助你既会用、又知其所以然。组件结构与导入方式Radio 组件由三个文件组成分别对应文档中讲解的三种形态src/radio/Radio.jsx基础单选框渲染为原生input typeradio加自定义外观src/radio/RadioGroup.jsx单选框组负责统一管理子项的选中状态并触发onChangesrc/radio/RadioButton.jsx按钮样式单选框继承自Radio外观呈按钮组。三者的装配在 src/radio/index.js 中完成通过静态属性挂接出文档示例中出现的Radio.Group与Radio.Button写法import Radio from ./Radio; import RadioButton from ./RadioButton; import RadioGroup from ./RadioGroup; Radio.Button RadioButton; Radio.Group RadioGroup; export default Radio;组件在库入口 src/index.js 中以export { default as Radio } from ./radio对外导出。对于 TypeScript 用户typings/index.d.ts 中声明了RadioProps、RadioGroupProps、RadioButtonProps三个接口且Radio类带有static Group: typeof RadioGroup与static Button: typeof RadioButton因此类型层面同样支持Radio.Group/Radio.Button的静态属性访问。需要说明适用前提本仓库基于 React 16 时代的 Class 组件编写peerDependencies中为react: *大量使用componentWillReceiveProps、childContextTypes等生命周期与 Context 写法阅读本文源码分析时需以此为前提。基础用法受控的选中状态官方文档指出单选框的选项默认全部可见不宜过多若选项过多应改用 Select 选择器。这是官方明确给出的选型建议。文档中的基础示例来自 site/docs/en-US/radio.md通过value绑定变量、checked指定选中状态完全由组件外部的state驱动constructor(props) { super(props); this.state { value: 1 } } onChange(value) { this.setState({ value }); } render() { return ( div Radio value1 checked{this.state.value 1} onChange{this.onChange.bind(this)}Option A/Radio Radio value2 checked{this.state.value 2} onChange{this.onChange.bind(this)}Option B/Radio /div ) }这个示例是典型的受控模式选中与否不依赖组件内部记忆而是每次render时由this.state.value计算得出。对应到源码Radio的选中判定逻辑在getChecked中src/radio/Radio.jsxgetChecked(props: Object): boolean { return props.model props.value || Boolean(props.checked) }也就是说一个Radio被视为选中当且仅当满足以下二者之一props.model单选框组注入的当前绑定值与props.value宽松相等所以数字1与字符串1也能匹配显式传入了checked{true}。独立使用Radio时走的是第二条路径。组件在构造与接收新 props 时都会重新计算checkedsrc/radio/Radio.jsxconstructor(props: Object) { super(props); this.state { checked: this.getChecked(props) }; } componentWillReceiveProps(props: Object) { const checked this.getChecked(props); if (this.state.checked ! checked) { this.setState({ checked }); } }用户点击时onChange处理函数先把外部回调传入this.props.value执行再更新内部checked状态src/radio/Radio.jsxonChange(e: SyntheticInputEventany) { const checked e.target.checked; if (checked) { if (this.props.onChange) { this.props.onChange(this.props.value); } } this.setState({ checked }); }注意回调参数就是该 Radio 的value这正是文档示例中onChange(value) { this.setState({ value }) }能工作的原因。渲染时checked、disabled与键盘焦点状态focus由onFocus/onBlur维护会被映射为is-checked、is-disabled、is-focus等 BEM 修饰类最终结构是labelspan classel-radio__input…input typeradio…/spanspan classel-radio__label{children || value}/span/label文案取自children无children时回退显示value。禁用状态disabled属性用于禁用单选框文档示例只需加上该属性即可render() { return ( div Radio value1 disabled{true}Option A/Radio Radio value2 disabled{true}Option B/Radio /div ) }从源码看disabled会同时落到两处内部状态类名is-disabled用于灰色视觉反馈以及原生input typeradio的disabled属性用于真正阻断交互二者见 src/radio/Radio.jsx。中文文档 site/docs/zh-CN/radio.md 在此处还强调了一条易错点选中与否的判断条件是绑定变量值等于value的值——禁用只影响交互不影响选中判定。单选框组 Radio.Group一次绑定统一管理当选项互斥时文档推荐使用Radio.Group组合Radio在Radio.Group上绑定value并监听onChange各Radio子项只声明自己的value无需再给每个 Radio 单独绑定变量constructor(props) { super(props); this.state { value: 3 } } onChange(value) { this.setState({ value }); } render() { return ( Radio.Group value{this.state.value} onChange{this.onChange.bind(this)} Radio value3Option A/Radio Radio value6Option B/Radio Radio value9Option C/Radio /Radio.Group ) }这一「父组件聚合状态」的能力核心实现在RadioGroup.render中src/radio/RadioGroup.jsxrender() { return ( div refRadioGroup style{this.style()} className{this.className(el-radio-group)} { React.Children.map(this.props.children, element { if (!element) { return null; } const { elementType } element.type; if (elementType ! Radio elementType ! RadioButton) { return null; } return React.cloneElement(element, Object.assign({}, element.props, { onChange: this.onChange.bind(this), model: this.props.value, size: this.props.size })) }) } /div ) }这里有三个值得注意的机制细节子项白名单过滤只有elementType为Radio或RadioButton的子节点才会被渲染其他子节点被静默过滤。两个组件分别通过static elementType Radio与static elementType RadioButton标识自身类型见 src/radio/Radio.jsx 与 src/radio/RadioButton.jsx。model注入Group 通过React.cloneElement把自己的value以model属性注入每个子项。这正好接上了上文getChecked的第一条判定props.model props.value——子项无需任何额外代码即可感知「谁是当前选中项」且由于使用了宽松相等value{3}数字能匹配value3字符串的子项这也是文档示例中state.value为数字而 Radio 的value是字符串却仍能正确高亮的原因。事件链路Group 把自己的onChange覆盖到子项的onChange上。子项被点击时Radio.onChange调用this.props.onChange(this.props.value)实际命中的是 Group 的onChangesrc/radio/RadioGroup.jsx后者再转发给使用者的回调。于是整条链路为原生 input change → Radio 上报自身 value → Group 转发 onChange(value) → 业务侧 setState。Group 自身还声明了disabled、size、textColor、fill等 props见 src/radio/RadioGroup.jsx分别服务于按钮样式与整组禁用场景下文继续展开。按钮样式 Radio.Buttonsize 与整组禁用文档建议想要按钮样式的单选组合时只需把Radio换成Radio.ButtonGroup 还提供size属性支持large与small不设定则为默认尺寸。完整示例覆盖了三行状态普通按钮组、含禁用项的按钮组、整组禁用的按钮组constructor(props) { super(props); this.state { radio3: New York, radio4: New York, radio5: New York } } onChange(key, value) { this.setState({ [key]: value }); } render() { return ( div Radio.Group value{this.state.radio3} onChange{this.onChange.bind(this, radio3)} Radio.Button valueNew York / Radio.Button valueWashington / Radio.Button valueLos Angeles / Radio.Button valueChicago / /Radio.Group Radio.Group value{this.state.radio4} onChange{this.onChange.bind(this, radio4)} Radio.Button valueNew York / Radio.Button valueWashington / Radio.Button valueLos Angeles disabled{true} / Radio.Button valueChicago / /Radio.Group Radio.Group value{this.state.radio5} disabled{true} Radio.Button valueNew York / Radio.Button valueWashington / Radio.Button valueLos Angeles / Radio.Button valueChicago / /Radio.Group /div ) }示例中onChange.bind(this, radio3)利用Function.prototype.bind的额外参数把「更新哪个 state 键」预绑定进回调配合计算属性[key]实现一个回调管理多组状态——这是三个按钮组复用同一处理函数的关键技巧。RadioButton通过 Context 与父级 Group 通信src/radio/RadioButton.jsxGroup 用getChildContext/childContextTypes把自身实例发布到component上下文键子项用contextTypes接收。基于这条通道三个能力得以实现尺寸继承size()从this.parent().props.size读取渲染时拼出el-radio-button--large或el-radio-button--small类名src/radio/RadioButton.jsx。这也解释了 Group 在cloneElement时同时注入size的用途。整组禁用isDisabled()返回this.props.disabled || this.parent().props.disabled即子项自身禁用或所属 Group 禁用按钮都会处于禁用态。文档示例第三行disabled{true}正是加在Radio.Group上实现整组禁用。激活态配色activeStyle()读取 Group 的fill激活时按钮的填充色与边框色与textColor激活时的文字颜色在选中this.state.checked为真时以内联样式应用到el-radio-button__inneractiveStyle(): { backgroundColor: string, borderColor: string, color: string } { return { backgroundColor: this.parent().props.fill || , borderColor: this.parent().props.fill || , color: this.parent().props.textColor || }; }文档参数表中给出的fill默认值#20a0ff、textColor默认值#ffffff来源于默认主题样式devDependencies 中的element-theme-default提供源码侧在未传入时回退为空字符串由 CSS 默认值接管。API 参数速查表以下表格完整继承自官方文档 site/docs/en-US/radio.md并结合源码做了标注。Radio 属性参数说明类型可选值默认值checked是否选中boolean—falselabelRadio 的值string/number/boolean——disabled是否禁用boolean—falsename原生 name 属性string——与源码的对应关系文档表格中label一列是沿用 Vue 版 Element 的命名习惯在本仓库的实现中真正生效的属性名是value且为必填项——Radio.propTypes声明了value: PropTypes.oneOfType([PropTypes.string, PropTypes.number]).isRequiredsrc/radio/Radio.jsx。所有官方示例与 TypeScript 声明typings/index.d.ts也一致使用value实际开发请以value为准。Radio-group 属性参数说明类型可选值默认值sizeRadio 按钮组尺寸stringlarge / small—fill按钮激活时的填充色和边框色string—#20a0fftextColor按钮激活时的文本颜色string—#ffffffdisabled整组禁用源码支持文档表格未单列boolean——disabled在 Group 的propTypes中有明确声明src/radio/RadioGroup.jsx并且上文按钮样式示例的第三行Radio.Group disabled{true}正是它的标准用法。Radio-group 事件事件名称说明回调参数onChange绑定值变化时触发选中 Radio 的 labelvalue值回调参数即被选中项的value经由Radio.onChange → this.props.onChange(this.props.value) → RadioGroup.onChange这条链路传递。Radio-button 属性参数说明类型可选值默认值labelRadio 的值源码中实际为valuestring/number——disabled是否禁用boolean—falseRadioButton.propTypes声明为value: PropTypes.oneOfType([PropTypes.string, PropTypes.number])src/radio/RadioButton.jsx。与基础Radio相比按钮形态不再单独渲染checked/name之外的输入类属性其选中、尺寸与配色全部由 Group 上下文决定。文档演示页面与样式入口上述所有示例均可在仓库文档站点中直接验证演示页 site/pages/radio/index.jsx 继承Markdown基类按语言加载对应文档require(../../docs/${locale}/radio.md)页面专用样式位于 site/pages/radio/style.scss。运行npm start对应 package.json 中的cd site node run.js即可在本地查看 Radio 页面的全部示例效果。小结独立使用Radio用value绑定选项值、checked由外部 state 计算选中判定为model value || Boolean(checked)组合使用Radio.GroupGroup 通过cloneElement注入model与onChange实现单点绑定、统一事件出口子项仅保留value声明按钮样式Radio.Button通过 Context 读取 Group 的size/disabled/fill/textColor尺寸映射为--large/--small修饰类激活配色以内联样式下发选项过多时改用 Select这是官方文档给出的明确选型边界。完整参考路径实现见 src/radio/类型声明见 typings/index.d.ts中文文档对照见 site/docs/zh-CN/radio.md。赞分享前端UI组件设计系统【免费下载链接】element-reactElement UI项目地址https://gitcode.com/gh_mirrors/el/element-react点击查看免费下载相关推荐Hoppscotch 自托管教程一条命令跑起完整的开源 API 调试平台Hoppscotch 自托管教程一条命令跑起完整的开源 API 调试平台 Hoppscotch 是一款开源 API 开发工具REST、GraphQL、Web开发工具接口测试前端后端CLINaive UI 单选组件n-radio / n-radio-group / n-radio-button完整指南API、受控与非受控、按钮组与主题定制Naive UI 单选组件n radio / n radio group / n radio button完整指南API、受控与非受控、按钮组与主题定制前端UI组件Shoelace 单选框组件sl-radio完全指南结合 sl-radio-group 构建单选表单控件Shoelace 单选框组件sl radio完全指南结合 sl radio group 构建单选表单控件 Shoelace 的 sl radio 是一个基UI组件前端创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关新闻

密码与加密技术复习指南:从对称加密到PKI的网络安全知识框架

密码与加密技术复习指南:从对称加密到PKI的网络安全知识框架

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

2026/10/14 1:07:04 阅读更多 →
Dart List实战指南:从增删改查到Flutter状态管理踩坑总结

Dart List实战指南:从增删改查到Flutter状态管理踩坑总结

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

2026/10/14 1:06:04 阅读更多 →
HMM隐马尔可夫模型Python实现:前向算法、Viterbi与Baum-Welch实战

HMM隐马尔可夫模型Python实现:前向算法、Viterbi与Baum-Welch实战

HMM(Hidden Markov Model,隐马尔可夫模型)这个名词,做 NLP、语音识别、行为序列分析的开发者应该都不陌生。我记得刚入门的时候,教材翻了好几遍,图模型和公式推导都能看懂,但一到写代码就卡住—…

2026/10/14 1:06:04 阅读更多 →

最新新闻

基于RT-Thread的贪吃蛇与俄罗斯方块:RTOS多线程与LCD渲染实战

基于RT-Thread的贪吃蛇与俄罗斯方块:RTOS多线程与LCD渲染实战

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

2026/10/14 1:44:13 阅读更多 →
ADC转换实战汇总:采样原理、噪声抑制与校准技巧

ADC转换实战汇总:采样原理、噪声抑制与校准技巧

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

2026/10/14 1:44:13 阅读更多 →
MATLAB highpass函数详解:从滤波原理到工程实战

MATLAB highpass函数详解:从滤波原理到工程实战

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

2026/10/14 1:44:13 阅读更多 →
YOLO26改进-Neck | LPRMAlignUpModule:局部像素关系建模对齐上采样,缓解跨尺度融合中的细节损失 | TPAMI2025

YOLO26改进-Neck | LPRMAlignUpModule:局部像素关系建模对齐上采样,缓解跨尺度融合中的细节损失 | TPAMI2025

前言 本文介绍了局部像素关系对齐上采样模块(LPRMAlignUpModule)在YOLO26中的结合应用。该模块通过压缩特征预测局部像素关系,并利用不同膨胀率的动态关系对跨尺度特征进行对齐与细化,增强上采样过程中的局部结构表达能力。我们将…

2026/10/14 1:44:13 阅读更多 →
Cloud 3.0 实战:算力调度、应用交付与成本优化的三大挑战

Cloud 3.0 实战:算力调度、应用交付与成本优化的三大挑战

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

2026/10/14 1:44:13 阅读更多 →
组合导航中的杆臂效应与外参标定:从原理到工程实践

组合导航中的杆臂效应与外参标定:从原理到工程实践

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

2026/10/14 1:43:13 阅读更多 →

日新闻

AnyPS5通用适配层设计:兼容性与性能的工程取舍

AnyPS5通用适配层设计:兼容性与性能的工程取舍

1. 从"AnyPS5"这个名字说起:它到底想解决什么问题第一次看到"AnyPS5"这个标题,我脑子里冒出来的第一个念头是:这大概率是一个围绕"跨平台运行"或者"通用适配"做文章的项目。名字里的"Any"…

2026/10/14 0:00:41 阅读更多 →
Flutter跨平台开发实战:二手交易应用与HarmonyOS适配

Flutter跨平台开发实战:二手交易应用与HarmonyOS适配

1. 项目概述:Flutter跨平台二手交易应用开发作为一名长期从事移动应用开发的工程师,我最近完成了一个基于Flutter框架的二手物品交易平台项目。这个项目最吸引我的地方在于它完美结合了Flutter的跨平台优势与HarmonyOS的生态特性,实现了"…

2026/10/14 0:00:41 阅读更多 →
DFS算法解决飞机降落调度问题实战

DFS算法解决飞机降落调度问题实战

1. 项目背景与核心思路飞机降落问题是一个经典的调度优化场景,也是算法竞赛和面试中的高频题目。这个题目要求我们合理安排多架飞机的降落顺序和时间,确保所有飞机都能安全着陆而不发生冲突。在实际航空管制中,这类问题直接关系到飞行安全和机…

2026/10/14 0:00:41 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/13 2:54:56 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/13 16:22:04 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/13 1:58:08 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

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

2026/10/13 22:01:27 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

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

2026/10/13 14:57:39 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

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

2026/10/12 18:11:17 阅读更多 →