antd Checkbox 禁用态(Disabled)深入解析:从 Demo 到源码的完整实践指南
本指南围绕 ant-design 仓库中 Checkbox 组件的 Disabled 示例文档 展开,讲解如何让单个或整组复选框进入不可用状态、三种典型禁用形态(未选、半选、已选)的呈现差异,并下沉到 disabled 属性合并优先级、ConfigProvider 全局禁用上下文与禁用态样式 Token 的源码实现。读完你可以直接照抄示例代码完成「禁用复选框」场景,同时理解禁用态背后从 prop 到 class、再到主题 Token 的完整渲染链路。
示例文档与运行效果:一屏演示三种禁用形态
在仓库 components/checkbox/demo/disabled.tsx 中,通过一个纵向 Flex 容器罗列了三个禁用复选框:
import React from 'react';
import { Checkbox, Flex } from 'antd';
const App: React.FC = () => (
<Flex vertical gap="medium">
<Checkbox defaultChecked={false} disabled />
<Checkbox indeterminate disabled />
<Checkbox defaultChecked disabled />
</Flex>
);
export default App;
与之配套的文档页 components/checkbox/demo/disabled.md 仅用一句话点明主题(zh-CN:checkbox 不可用;en-US:Disabled checkbox.),因此理解这个示例的关键在于解读三个复选框背后的状态组合:
| 复选框 | 关键属性 | 视觉语义 |
|---|---|---|
| 第 1 个 | defaultChecked={false} + disabled |
未选中的禁用复选框(默认形态) |
| 第 2 个 | indeterminate + disabled |
半选(不确定态)的禁用复选框 |
| 第 3 个 | defaultChecked + disabled |
已选中的禁用复选框 |
三点值得注意:
- 三个复选框都没有
checked受控属性,说明本示例演示的是非受控 + 禁用的组合;禁用后用户点击也不会触发内部状态更新,因此defaultChecked的初始值会被完整保留。 indeterminate属于「外观态」,它并不表示第三个勾选状态,只负责渲染一横线的半选图形;与disabled叠加后仍以禁用配色呈现。- 组件的渲染快照(见 demo.test.tsx 快照 中对应片段)显示,三个禁用项分别渲染出
ant-checkbox-wrapper-disabled、ant-checkbox-indeterminate与ant-checkbox-checked等 class 组合,<input>上都带有原生disabled属性。
API 入口:Checkbox 与 Checkbox.Group 的禁用配置
单个 Checkbox 的 disabled
组件 components/checkbox/index.en-US.md 的 API 表格给出了单选复选框的核心属性:disabled(If disable checkbox,boolean,默认 false)。此外本示例用到的相关属性还包括:
| 属性 | 说明 | 默认值 |
|---|---|---|
checked |
是否勾选(受控) | false |
defaultChecked |
初始勾选状态(非受控) | false |
indeterminate |
半选状态,仅影响外观 | false |
disabled |
是否禁用 | false |
这些 props 的 TypeScript 定义位于 Checkbox.tsx 的 AbstractCheckboxProps,其中 disabled?: boolean、defaultChecked?: boolean 均为可选属性。
Checkbox.Group 的两个禁用粒度
对于整组场景,Checkbox.Group 提供了两个层面的禁用入口(见 Group.tsx 与 index.en-US.md 的 Group API 表):
- 组级禁用:
<Checkbox.Group disabled>—— 一键让组内所有复选框不可用,无需逐个设置。 - 选项级禁用:仅在使用
options声明式定义时生效,Option对象中携带独立的disabled字段:
interface Option {
label: string;
value: string;
disabled?: boolean;
}
这一接口在 Group.tsx 中被扩展为 CheckboxOptionType,还支持 title、className(5.25.0+)、style、onChange、required 等字段。渲染时逐项处理禁用:
<Checkbox
disabled={'disabled' in option ? option.disabled : restProps.disabled}
...
>
即选项自身声明了 disabled 时以选项为准,否则回退到 Group 的 disabled。
源码剖析:disabled 是如何被合并与生效的
三级合并优先级:自身 prop > 组上下文 > ConfigProvider
在 Checkbox.tsx 中,禁用状态并不只是读取一个 prop:
const { isFormItemInput } = React.useContext(FormItemInputContext);
const contextDisabled = React.useContext(DisabledContext);
const mergedDisabled = disabled ?? checkboxGroup?.disabled ?? contextDisabled;
由此可以推断出禁用态的合并顺序为:
- Checkbox 自身的
disabledprop 优先级最高; - 其次取
checkboxGroup?.disabled,即来自Checkbox.Group的组级禁用,它通过 GroupContext 在组内传递; - 最后回退到
DisabledContext,这是由ConfigProvider提供的全局禁用上下文。
全局禁用层的实现位于 config-provider/DisabledContext.tsx:DisabledContextProvider 读取外层值并在自身未声明 disabled 时继续透传外层值(disabled ?? originDisabled)。也就是说,在 ConfigProvider 上开启禁用后,不显式写 disabled 的 Checkbox 也会被统一禁用,适合「整表只读」「表单提交中锁输入」等场景。
禁用态落到了哪里:DOM class 与原生 input
mergedDisabled 计算完成后,在 Checkbox.tsx 中被用于拼接两个关键 class:
- wrapper 层:
${prefixCls}-wrapper-disabled(即ant-checkbox-wrapper-disabled); - 图标层:内部传入的
disabled会让底层RcCheckbox渲染出ant-checkbox-disabled,并给原生<input type="checkbox">加上disabled属性。
同时组件被 <Wave> 包裹,渲染段 传入 disabled={mergedDisabled},用于禁用点击时由 antd Wave 产生的涟漪反馈。
禁用态样式:光标与配色 Token
禁用态的样式定义集中在 components/checkbox/style/index.ts,要点包括:
- wrapper 禁用时
cursor: not-allowed; - checkbox 及其原生 input 除
cursor: not-allowed外还会设置pointerEvents: none。源码注释说明(对应 issue 场景 #39822):关闭原生 input 的指针事件,是为了让外层容器(如 Tooltip)仍能正常接收并触发事件,即「禁用后仍可提示为什么禁用」; - 配色全部走主题 Token,保证与整体主题联动:
- 背景
token.colorBgContainerDisabled - 边框
token.colorBorder - 勾选对勾(
:after边框)与文字(& + span)使用token.colorTextDisabled - 半选态横线(
&${checkboxCls}-indeterminate::after)使用token.colorTextDisabled
- 背景
因此禁用 Checkbox 与已勾选/半选状态叠加时,勾号与横线都会统一变灰,而不是只对「未选」形态生效——这正是本示例三行复选框视觉统一的底层原因。由于禁用与 hover 相关规则互斥(样式中的 :hover 选择器都限定在 :not(...-disabled) 范围内),禁用项在悬浮时也不会出现主题色描边或主色填充变化。
测试验证:禁用态在渲染层的行为
仓库为该 demo 提供了自动化验证。快照文件 demo.test.tsx.snap 及 demo-extend.test.ts.snap 中记录了 renders components/checkbox/demo/disabled.tsx 的完整输出,可以核对到:
- 外层为
ant-flex ant-flex-vertical ant-flex-gap-medium容器; - 三个
<label>均带ant-checkbox-wrapper-disabled; - 中间一项的 icon 同时带
ant-checkbox-indeterminate,第三项带ant-checkbox-checked; - 每个
<input>上都有disabled属性且未被checked属性污染(未选项不带checked,已选项带checked)。
这些快照由 demo.test.tsx 与 demo-extend.test.tsx 生成,可作为「禁用的语义 class 与原生 input 属性正确下发」的回归证据;组件单元测试(checkbox.test.tsx、group.test.tsx)进一步覆盖了禁用交互、Group 级禁用与选项级禁用等行为。
常见叠加场景与注意事项
- 表单中禁用:Form.Item 默认把值绑定到
value,而 Checkbox 的状态字段是checked,需通过valuePropName="checked"绑定(见 index.en-US.md 的 FAQ)。对禁用项而言,提交时其值是否包含在表单值中,取决于 Form 收集逻辑,而非禁用本身。 - 禁用 + 受控:若同时传了
checked与disabled,禁用只是阻止用户交互;受控值仍可通过上层状态改变,useControlledState(见 Checkbox.tsx)确保外部checked始终优先。 - 禁用 + Tooltip:由于 disabled 时原生 input 关闭了指针事件但外层 label 仍可捕获事件,开发者可以在 Checkbox 外部包一层 Tooltip 实现「悬停解释禁用原因」的交互(仓库中还提供了该场景的调试示例 debug-disable-popover.tsx)。
- 全局禁用:通过
ConfigProvider注入的DisabledContext,可对子树内所有 Checkbox(乃至其他支持该上下文的组件)一键禁用,适合表格只读与批量锁定场景。 - 样式覆盖:若需自定义禁用配色,优先在
ConfigProvider主题中调整colorBgContainerDisabled、colorTextDisabled等全局 Token;Checkbox组件自身没有额外的禁用专项 ComponentToken,其禁用视觉完全由上述全局 Token 与通用边框 Token 推导而来(见 style/index.ts 中CheckboxToken仅含checkboxSize与checkboxCls可佐证)。
小结
「禁用复选框」虽然是 Checkbox 的一个小状态,但完整的支持横跨多个层次:单个 Checkbox 的 disabled prop、Checkbox.Group 的组级与选项级 disabled、ConfigProvider 的全局禁用上下文,以及最终映射到 ant-checkbox-wrapper-disabled / ant-checkbox-disabled class 与一组禁用主题 Token 的样式体系。理解 disabled.tsx 这短短十几行代码,就能同时掌握 antd 的禁用态优先级规则、非受控初始值行为以及如何用一套 Token 保持禁用视觉与主题一致,可直接复用到表单锁定、只读列表、批量操作受限等真实业务场景。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0624
Hy4-previewHy4 preview 是由腾讯混元团队研发的新一代混合专家(MoE)旗舰模型。模型总参数量 770B,每个 token 激活 49B,主干共包含78层,第一层采用标准 FFN,其余 77 层均为 MoE 结构,每层包含 256 个路由专家与 1 个共享专家,每个 token 激活 top-8 路由专家及共享专家。主干之外原生内置 1 层 MTP(总参数量 10B,激活 0.7B)以支持投机解码。Python00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
GLM-5.3-FlashGLM-5.3-Flash (320B-A18B),是GLM-5系列的首个原生多模态模型。320B总参数,能力超过GLM-5.2Jinja00
Spark-X2.5-4BSpark-X2.5-4B 旨在让强大的 AI 更实用、更高效、更易获得。在广泛日常任务中表现强劲,涵盖对话、写作、翻译、推理、编码、工具调用以及智能体工作流,并在同等规模的开源模型中取得领先成绩。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00