前端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),仅供参考