ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

element-react Radio 单选框组件完全指南:从基础用法到源码原理

element-react Radio 单选框组件完全指南:从基础用法到源码原理
  • 前端
  • UI组件
  • 设计系统

【免费下载链接】element-react

Element UI

项目地址:https://gitcode.com/gh_mirrors/el/element-react
点击查看免费下载

本篇技术指南以 radio.md 为骨架,系统讲解 element-react 中 Radio 单选框组件的基础用法、禁用状态、单选框组与按钮样式,并结合仓库源码剖析其选中判定、组内联动与按钮样式实现的底层机制。读者学完后可以熟练地在 React 应用中正确接入 Radio 组件、理解checked与value的判定关系,并能按需扩展按钮组样式与交互行为。

组件定位:在一组备选项中进行单选

Radio 单选框用于在多个互斥的选项中选择一个场景。与 Checkbox 不同,Radio 一旦选中即表示该组内其余选项不再可选(同一时刻只能有一个选中态)。由于 Radio 选项默认全部可见,官方文档建议选项不宜过多;当选项数量较多时,应改用 Select 选择器(对应组件见 site/pages/index.jsx 中 Form 分类下的select)。

在 element-react 中,Radio 被设计为三个协同工作的子组件,并在 src/radio/index.js 中完成挂载:

import Radio from './Radio'; import RadioButton from './RadioButton'; import RadioGroup from './RadioGroup'; Radio.Button = RadioButton; Radio.Group = RadioGroup; export default Radio;

因此使用方可以Radio.Group与Radio.Button的静态属性形式直接访问子组件,同时Radio本身也作为整体从 src/index.js 统一导出,支持import { Radio } from 'element-react'。

基础用法:绑定变量并通过 checked 控制选中

使用 Radio 组件时,需要为每个选项设置value绑定变量,并通过checked指定当前 Radio 的选中状态。完整的受控用法如下(摘自 radio.md):

constructor(props) { super(props); this.state = { value: 1 } } onChange(value) { this.setState({ value }); } render() { return ( <div> <Radio value="1" checked={this.state.value === 1} onChange={this.onChange.bind(this)}>备选项</Radio> <Radio value="2" checked={this.state.value === 2} onChange={this.onChange.bind(this)}>备选项</Radio> </div> ) }

这段代码的关键在于:选中的条件是绑定的变量值等于value中的值。checked={this.state.value === 1}将组件状态与选项值建立严格的相等关系,点击任一选项触发onChange后更新state.value,React 重新渲染时两个 Radio 的checked自然互斥。

从源码角度验证这一判定逻辑,见 src/radio/Radio.jsx:

getChecked(props) { return props.model == props.value || Boolean(props.checked) }

Radio的选中态由两个来源共同决定:

  • model == value:当 Radio 处于组内(由Radio.Group通过cloneElement注入model,值为组的value)时,通过宽松相等比较当前选项值;
  • Boolean(props.checked):单独使用时,直接以checked属性为准。

此外 src/radio/Radio.jsx 中的componentWillReceiveProps会在父组件传入新的props后同步内部checked状态,保证受控模式下 UI 与数据一致。组件底层渲染为原生<input type="radio">,并包裹在el-radio语义化结构中(输入框el-radio__input、圆形标识el-radio__inner、文本el-radio__label),见 src/radio/Radio.jsx。

禁用状态

当选项当前不可用时,为Radio设置disabled属性即可,它接受一个Boolean,true为禁用:

render() { return ( <div> <Radio value="1" disabled={true}>备选项</Radio> <Radio value="2" disabled={true}>备选项</Radio> </div> ) }

源码层面,disabled直接透传给原生 input(src/radio/Radio.jsx),同时给输入框容器追加is-disabled类(src/radio/Radio.jsx),从而在样式上呈现置灰效果并阻断点击交互。注意 Radio 组件本身未对onChange做额外的禁用拦截,行为完全依赖原生disabled,因此在自定义封装时也应保留该属性传递。

单选框组:Radio.Group 统一管理选中值

在“多个互斥选项中选择一个”的场景,推荐使用Radio.Group组合子元素Radio。组的value绑定当前选中值,每个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 value="3">备选项</Radio> <Radio value="6">备选项</Radio> <Radio value="9">备选项</Radio> </Radio.Group> ) }

Radio.Group的onChange事件在绑定值变化时触发,回调参数为被选中的 Radio 的 label(value)值。

组联动的源码机制

Radio.Group的核心实现见 src/radio/RadioGroup.jsx:

  1. 子组件识别:通过React.Children.map遍历子元素,读取element.type.elementType静态属性,仅保留Radio与RadioButton类型(src/radio/RadioGroup.jsx),其余子元素被过滤;
  2. 属性注入:通过React.cloneElement为每个合法子元素注入onChange、model(组的value)与size(src/radio/RadioGroup.jsx),这正是组内 Radio 无需手动绑定变量的原因——选中判定统一由model == value完成;
  3. 事件统一:子元素的onChange被替换为组实例的onChange,最终向外抛出一个value参数(src/radio/RadioGroup.jsx);
  4. 上下文注入:getChildContext将组实例放入 React 上下文(src/radio/RadioGroup.jsx),供RadioButton读取父组配置(如fill、textColor、size)。

按钮样式:Radio.Button 与 size 尺寸

将Radio元素换成Radio.Button即可获得按钮样式的单选组合。Radio.Group提供size属性控制按钮组尺寸,支持large和small两种(不设定时为默认尺寸):

constructor(props) { super(props); this.state = { radio3: '上海', radio4: '上海', radio5: '上海' } } onChange(key, value) { this.setState({ [key]: value }); } render() { return ( <div> <Radio.Group value={this.state.radio3} onChange={this.onChange.bind(this, 'radio3')}> <Radio.Button value="上海" /> <Radio.Button value="北京" /> <Radio.Button value="广州" /> <Radio.Button value="深圳" /> </Radio.Group> <Radio.Group value={this.state.radio4} onChange={this.onChange.bind(this, 'radio4')}> <Radio.Button value="上海" /> <Radio.Button value="北京" /> <Radio.Button value="广州" disabled={true} /> <Radio.Button value="深圳" /> </Radio.Group> <Radio.Group value={this.state.radio5} disabled={true}> <Radio.Button value="上海" /> <Radio.Button value="北京" /> <Radio.Button value="广州" /> <Radio.Button value="深圳" /> </Radio.Group> </div> ) }

上述三组分别演示了:普通按钮组、单项禁用按钮组(广州被disabled)、整组禁用(Radio.Group上的disabled)。

RadioButton 的实现细节

RadioButton继承自Radio(src/radio/RadioButton.jsx),在父类基础上扩展了三个能力:

  • 禁用合并:isDisabled()返回this.props.disabled || this.parent().props.disabled(src/radio/RadioButton.jsx),即单项禁用与组级禁用取并集;
  • 尺寸:size()从父组props.size读取,渲染时拼接el-radio-button--large/el-radio-button--small类(src/radio/RadioButton.jsx);
  • 激活配色:activeStyle()读取父组的fill与textColor,选中态下应用到按钮内层 span 的backgroundColor、borderColor与color(src/radio/RadioButton.jsx)。

其中parent()依赖RadioGroup注入的 React 上下文(context.component),通过 src/radio/RadioGroup.jsx 声明的childContextTypes建立父子通信,这正是按钮组样式配置能够统一生效的桥梁。

API 一览

Radio Attributes

参数说明类型可选值默认值
checkedRadio 是否被选中boolean—false
valueRadio 的 valuestring, number, boolean——
disabled是否禁用boolean—false
name原生 name 属性string——

Radio-group Attributes

参数说明类型可选值默认值
sizeRadio 按钮组尺寸stringlarge, small—
fill按钮激活时的填充色和边框色string—#20a0ff
textColor按钮激活时的文本颜色string—#ffffff

Radio-group Events

事件名称说明回调参数
onChange绑定值变化时触发的事件选中的 Radio label 值

Radio-button Attributes

参数说明类型可选值默认值
valueRadio 的 valuestring, number——
disabled是否禁用boolean—false

补充说明:value在组件层面(src/radio/Radio.jsx)被声明为string | number的必填属性(isRequired),同时checked与disabled均为可选布尔值;name在 RadioButton 中同样可用(src/radio/RadioButton.jsx)。文档表格中的boolean支持来自 typings/index.d.ts 的类型声明扩展。

进阶:TypeScript 类型支持

element-react 在 typings/index.d.ts 中为 Radio 系列组件提供了完整的 TypeScript 声明:

interface RadioProps extends ElementReactLibs.ComponentProps<{}> { value: string | number | boolean onChange?(value?: string | number | boolean): void disabled?: boolean checked?: boolean name?: string } interface RadioGroupProps extends ElementReactLibs.ComponentProps<{}> { value?: string | number disabled?: boolean size?: 'large' | 'small' textColor?: string fill?: string onChange?(value?: string | number): void } interface RadioButtonProps extends ElementReactLibs.ComponentProps<{}> { value: string | number disabled?: boolean name?: string } export class Radio extends ElementReactLibs.Component<RadioProps, {}> { static Group: typeof RadioGroup static Button: typeof RadioButton }

类型测试文件 typings/typing-tests/Radio.tsx 覆盖了全部属性的编译验证,包括value传布尔值、Radio.Group的size="large" | "small"、fill/textColor配色以及Radio.Button的单项禁用等场景。使用 TypeScript 的开发者可以参考该文件确认类型约束。

安装与使用

element-react 通过 npm 安装,并配合 Element 默认主题使用:

npm install element-react --save npm install element-theme-default --save

然后在组件中引入:

import { Radio } from 'element-react';

如果希望结合 Rollup.js 或 Webpack 2 实现 tree-shaking,可以使用element-react/next入口:import { Radio } from 'element-react/next'。详细的 webpack 加载器配置(babel-loader、css-loader、file-loader)参见 README.md。

总结

通过本文可以得出 element-react Radio 单选框组件的完整使用链路:

  • 单独使用:value+checked+onChange构成受控单选,选中判定为model == value || Boolean(checked);
  • 组内使用:Radio.Group统一注入model与onChange,子组件零绑定变量即可互斥单选;
  • 按钮样式:Radio.Button继承Radio,通过 React 上下文读取父组的size、fill、textColor,实现按钮化单选与配色定制;
  • 类型保障:仓库提供 typings/index.d.ts 完整声明与 Radio.tsx 编译验证,可安全接入 TypeScript 项目。

从文档(site/docs/zh-CN/radio.md)到源码(src/radio/)再到类型声明(typings/index.d.ts),Radio 组件的每一层设计都有清晰依据,便于开发者放心地在其之上封装业务级单选交互。

  • 前端
  • UI组件
  • 设计系统

【免费下载链接】element-react

Element UI

项目地址:https://gitcode.com/gh_mirrors/el/element-react
点击查看免费下载

相关推荐

上一篇:如何根治DeepSeek-OCR-2输出复读:NoRepeatNGram白名单LogitsProcessor实现详解
下一篇:Fugleramme三种显示模式详解:Collage拼贴、最新鸟类与最新抵达,哪款适合你

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

RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进