Ant Design Cascader 级联选择器完全指南:API 解析与源码级实践
本指南基于 Ant Design 仓库 components/cascader/index.en-US.md 整理,系统讲解级联选择组件 Cascader 的应用场景、全部配置 API、showSearch 搜索子配置、Option 数据结构、Cascader.Panel 面板用法以及语义化 DOM 定制能力。文中结合 组件主入口源码 与目录内真实可运行示例(demo)逐项印证参数行为,帮助你在省市区、组织层级、商品分类等树形选择场景中高效落地。
何时使用(When To Use)
Cascader 面向“多级关联数据”的单选/多选交互,官方文档给出了三类典型场景:
- 从一组关联数据集中选择,例如省 / 市 / 区、公司层级、事物分类;
- 从大数据集中选择,数据带有清晰的多级分类,逐级分离便于挑选;
- 在一个浮层中完成级联项选择,以获得更佳的用户体验。
从源码结构看,Ant Design 的 Cascader 是基于 @rc-component/cascader(RcCascader)二次封装的“Select 风格”组件:index.tsx 引入了 RcCascader 与其 BaseOptionType、DefaultOptionType、SearchConfig 等类型,同时复用了 Select 的样式系统(useSelectStyle、mergedBuiltinPlacements)与图标工具(useSelectIcons、usePopupRender、useShowArrow),因此它在外观与行为上(搜索列表、悬浮透明度、命中高亮等)与 Select 保持设计一致。
快速上手:Basic 示例
Basic 示例 展示了最标准的省市区数据模型:options 是一个带 children 的树,onChange 返回“自顶向下的值路径数组”:
import React from 'react';
import type { CascaderProps } from 'antd';
import { Cascader } from 'antd';
type Option = {
value: string;
label: string;
children?: Option[];
};
const options: Option[] = [
{
value: 'zhejiang',
label: 'Zhejiang',
children: [
{
value: 'hangzhou',
label: 'Hangzhou',
children: [
{ value: 'xihu', label: 'West Lake' },
],
},
],
},
// ...
];
const onChange: CascaderProps<Option>['onChange'] = (value) => {
console.log(value); // ['zhejiang', 'hangzhou', 'xihu']
};
const App: React.FC = () => (
<Cascader options={options} onChange={onChange} placeholder="Please select" />
);
export default App;
官方文档给出最小使用范式 {/* prettier-ignore */}<Cascader options={options} onChange={onChange} />,value 与 defaultValue 的类型为 string[] | number[],即每一级取值的路径序列。完整可运行源码见 basic.tsx。
核心 API 全解析
官方文档的 API 表是理解组件行为的权威索引,以下保留全部字段,并补充取值语义与版本说明。通用属性(如 id、className、aria 相关等)参照 Common props。
| 属性 | 说明 | 类型 | 默认值 | 版本 | 全局配置 |
|---|---|---|---|---|---|
allowClear |
是否显示清除按钮 | boolean | { clearIcon?: ReactNode } |
true |
5.8.0 起支持对象写法 | clearIcon:6.4.0 |
autoClearSearchValue |
选中某项后是否清空当前搜索词,仅 multiple 模式生效 |
boolean |
true |
5.9.0 | × |
bordered |
是否有边框,已废弃,请改用 variant |
boolean |
true |
— | × |
changeOnSelect |
设为 true 时每次选择都会触发值变化(无需选到叶子) |
boolean |
false |
— | × |
classNames |
定制组件内部各语义结构的 className,支持对象或函数 | Record<SemanticDOM, string> | (info: { props }) => Record<SemanticDOM, string> |
— | — | 5.25.0 |
defaultOpen |
级联浮层初始是否可见 | boolean |
— | — | × |
defaultValue |
初始选中值(路径数组) | string[] | number[] |
[] |
— | × |
disabled |
是否禁用 | boolean |
false |
— | × |
displayRender |
选中项展示的渲染函数 | (label, selectedOptions) => ReactNode |
label => label.join('/') |
multiple 支持 4.18.0 |
× |
tagRender |
multiple 模式下标签的自定义渲染函数 |
(label: string, onClose: function, value: string) => ReactNode |
— | — | × |
popupClassName |
浮层附加 className,改用 classNames.popup.root |
string |
— | 4.23.0 | × |
dropdownClassName |
浮层附加 className,改用 classNames.popup.root |
string |
— | — | × |
dropdownRender |
自定义下拉内容,改用 popupRender |
(menus: ReactElement) => ReactNode |
— | 4.4.0 | × |
popupRender |
自定义下拉内容 | (menus: ReactElement) => ReactNode |
— | — | × |
dropdownStyle |
下拉菜单样式,改用 styles.popup.root |
CSSProperties |
— | — | × |
expandIcon |
自定义当前项的展开图标 | ReactNode |
— | 4.4.0 | 6.3.0 |
expandTrigger |
展开当前项的触发方式 | 'click' | 'hover' |
click |
— | × |
fieldNames |
自定义 label、value、children 的字段名 |
object |
{ label: 'label', value: 'value', children: 'children' } |
— | × |
getPopupContainer |
浮层渲染到的父节点,默认 body;出现定位问题时改挂到可滚动容器并设为相对定位 |
(triggerNode) => HTMLElement |
() => document.body |
— | × |
loadData |
懒加载选项,不能与 showSearch 同时使用 |
(selectedOptions) => void |
— | — | × |
loadingIcon |
自定义加载图标 | ReactNode |
— | — | 6.3.0 |
maxTagCount |
最多展示的标签数,responsive 会牺牲渲染性能 |
number | 'responsive' |
— | 4.17.0 | × |
maxTagPlaceholder |
被隐藏标签的占位内容 | ReactNode | (omittedValues) => ReactNode |
— | 4.17.0 | × |
maxTagTextLength |
标签文案最大展示长度 | number |
— | 4.17.0 | × |
notFoundContent |
无匹配结果时展示的内容 | ReactNode |
No data |
— | × |
open |
级联浮层是否可见(受控) | boolean |
— | 4.17.0 | × |
options |
级联数据选项 | Option[] |
— | — | × |
placeholder |
输入框占位符 | string |
— | — | × |
placement |
浮层预设对齐位置 | bottomLeft | bottomRight | topLeft | topRight |
bottomLeft |
4.17.0 | × |
prefix |
自定义前缀图标/内容 | ReactNode |
— | 5.22.0 | × |
showArrow |
是否展示箭头图标,废弃,请用 suffixIcon={null} 隐藏 |
boolean |
true |
— | × |
showSearch |
单选模式下是否展示搜索框 | boolean | Object |
false |
— | searchIcon:6.4.0 |
size |
输入框尺寸 | 'large' | 'medium' | 'small' |
medium |
— | × |
status |
校验状态 | 'error' | 'warning' |
— | 4.19.0 | × |
styles |
定制组件内部各语义结构的内联样式,支持对象或函数 | Record<SemanticDOM, CSSProperties> | (info: { props }) => Record<SemanticDOM, CSSProperties> |
— | — | 5.25.0 |
suffixIcon |
自定义后缀图标 | ReactNode |
— | — | 6.4.0 |
value |
受控选中值(路径数组) | string[] | number[] |
— | — | × |
variant |
选择器形态 | 'outlined' | 'borderless' | 'filled' | 'underlined' |
outlined |
5.13.0;underlined:5.24.0 |
5.19.0 |
onChange |
完成级联选择后的回调 | (value, selectedOptions) => void |
— | — | × |
onClear |
点击清除时回调 | () => void |
— | — | × |
onDropdownVisibleChange |
浮层显隐回调,改用 onOpenChange |
(value) => void |
— | 4.17.0 | × |
onOpenChange |
浮层显隐回调 | (value) => void |
— | — | × |
onPopupVisibleChange |
浮层显隐回调,改用 onOpenChange |
(value) => void |
— | — | × |
multiple |
是否多选(勾选模式) | boolean |
— | 4.17.0 | × |
removeIcon |
自定义移除图标 | ReactNode |
— | — | 6.4.0 |
showCheckedStrategy |
多选回显策略(仅 multiple 生效):Cascader.SHOW_CHILD 仅显示子节点;Cascader.SHOW_PARENT 在父节点下所有子节点都被勾选时仅显示父节点 |
Cascader.SHOW_PARENT | Cascader.SHOW_CHILD |
Cascader.SHOW_PARENT |
4.20.0 | × |
searchValue |
设置搜索词,需配合 showSearch |
string |
— | 4.17.0 | × |
onSearch |
输入变化回调 | (search: string) => void |
— | 4.17.0 | × |
dropdownMenuColumnStyle |
下拉菜单列样式,改用 styles.popup.listItem |
CSSProperties |
— | — | × |
popupMenuColumnStyle |
下拉菜单列样式,改用 styles.popup.listItem |
CSSProperties |
— | — | × |
optionRender |
自定义下拉选项的渲染 | (option: Option) => React.ReactNode |
— | 5.16.0 | × |
废弃 API 的运行时迁移提示
仓库在开发模式下会对废弃属性打印告警(index.tsx),映射关系一目了然:
dropdownClassName→classNames.popup.rootdropdownStyle→styles.popup.rootdropdownRender→popupRenderdropdownMenuColumnStyle/popupMenuColumnStyle→styles.popup.listItemonDropdownVisibleChange/onPopupVisibleChange→onOpenChangebordered→variantshowArrow→ 通过suffixIcon={null}隐藏箭头
实现上,这些迁移在 index.tsx 统一收敛:mergedPopupRender = usePopupRender(popupRender || dropdownRender)、mergedPopupStyle = { ...mergedStyles.popup.root, ...dropdownStyle }、mergedOnOpenChange 依次回退取新 API,做到新旧属性兼容过渡。
多选与回显策略
multiple 开启后选项前出现 Checkbox,勾选支持父子级联。回显由 showCheckedStrategy 控制,它引用自 RcCascader 暴露的常量 SHOW_CHILD / SHOW_PARENT(index.tsx),并被挂到组件静态属性 Cascader.SHOW_PARENT / Cascader.SHOW_CHILD(index.tsx)。示例可对照 showCheckedStrategy.tsx:默认值里同时勾选了 bamboo/little 下三个叶子时,SHOW_CHILD 回显三片叶子标签,SHOW_PARENT 只回显父路径标签;标签溢出时可用 maxTagCount="responsive" 响应式折叠。
多选基础用法见 multiple.tsx,其 Option 额外演示了 disableCheckbox 字段(禁用单个节点的勾选框但不禁用浏览)。
形态:size、variant、status 与前后缀
- size:
large/medium(默认)/small,源码在渲染时追加${prefixCls}-lg/${prefixCls}-sm类并受 ConfigProvidercomponentSize与 Space.Compact 上下文合并(index.tsx)。 - variant:
outlined/filled/borderless/underlined,通过useVariant('cascader', customVariant, bordered)与表单上下文联动(index.tsx),与 Input、Select 视觉统一。 - status:
error/warning,可配合 Form.ItemvalidateStatus自动透传;组件通过FormItemInputContext读取表单态并合并getStatusClassNames(index.tsx)。 - prefix / suffixIcon / clearIcon / removeIcon / loadingIcon / expandIcon / searchIcon:分别定制前缀、下拉箭头、清除、移除、加载、展开、搜索图标;
expandIcon、loadingIcon等支持在 ConfigProvider 组件级配置中统一注入(源码通过useComponentConfig('cascader')与 hooks/useIcons.ts 完成合并)。对应示例见 suffix.tsx、variant.tsx、status.tsx。
搜索:showSearch 子配置
单选模式下设置 showSearch 可开启搜索(官方同时给出布尔值与对象两种形式),其子配置如下:
| 属性 | 说明 | 类型 | 默认值 | 版本 |
|---|---|---|---|---|
autoClearSearchValue |
选中某项后清空当前搜索词,仅 multiple 模式生效 |
boolean |
true |
5.9.0 |
filter |
过滤函数,接收 inputValue 与路径 path,返回 true 保留该选项 |
(inputValue, path) => boolean |
— | — |
limit |
过滤结果数量上限 | number | false |
50 |
— |
matchInputWidth |
列表宽度是否匹配输入框 | boolean |
true |
— |
render |
渲染过滤后的选项 | (inputValue, path) => ReactNode |
— | — |
sort |
过滤结果排序函数 | (a, b, inputValue) => number |
— | — |
searchValue |
设置搜索词(受控),需配合 showSearch |
string |
— | 4.17.0 |
onSearch |
输入变化回调 | (search: string) => void |
— | 4.17.0 |
searchIcon |
自定义搜索图标 | ReactNode |
— | 6.3.0 |
官方示例 search.tsx 采用“路径命中”过滤:只要路径上任一节点的 label 包含关键词即命中,同时用 onSearch 观察输入过程:
const filter = (inputValue: string, path: DefaultOptionType[]) =>
path.some((option) =>
(option.label as string).toLowerCase().includes(inputValue.toLowerCase()),
);
const App: React.FC = () => (
<Cascader
options={options}
onChange={onChange}
placeholder="Please select"
showSearch={{ filter, onSearch: (value) => console.log(value) }}
/>
);
在默认情况下(showSearch 为 true 或对象但未提供 render),命中结果按完整路径以 / 连接展示,关键词会被包裹进 ${prefixCls}-menu-item-keyword 高亮节点;这一逻辑实现在组件内的 highlightKeyword 与 defaultSearchRender(index.tsx),它先把文案按小写关键词切分重组,再把奇数位片段渲染为高亮 <span>。isPlainObject(showSearch) 时会把用户子配置浅合并进带默认 render 的搜索配置(index.tsx)。
Option 数据结构与字段映射
interface Option {
value: string | number;
label?: React.ReactNode;
disabled?: boolean;
children?: Option[];
// 指定 loadData 时决定该节点是否为叶子节点。
// false 会强制把该节点当作父节点(即使当前没有 children)。
// 无 children 时也强制展示展开图标。
isLeaf?: boolean;
}
要点说明:
value支持string | number,与value/defaultValue/onChange的string[] | number[]路径语义对应;label为ReactNode,支持富文本节点,例如带图标的层级名称;disabled置灰该节点,无法选中;children递归定义子树,缺省即视为叶子;isLeaf只在与loadData配合时才有意义:设false会强制把该节点视作可展开的父节点,即便当前没有children,也会显示展开图标触发懒加载。
自定义字段名 fieldNames
后端数据字段名不一定是 label/value/children 时,用 fieldNames 重映射,默认值为 { label: 'label', value: 'value', children: 'children' }。官方示例 fields-name.tsx 将接口字段 code/name/items 映射为标准结构:
<Cascader
fieldNames={{ label: 'name', value: 'code', children: 'items' }}
options={options}
onChange={onChange}
placeholder="Please select"
/>
懒加载 loadData
数据量过大、层级动态产生时使用 loadData 按需加载。官方示例 lazy.tsx 展示了标准写法:根节点先声明 isLeaf: false,loadData(selectedOptions) 取路径末位节点,通过异步请求为其填充 children 后基于不可变更新触发重渲染;同时开启 changeOnSelect 使父级可直接选中。注意:loadData 不能与 showSearch 并存(官方文档明确注明)。加载中的旋转动画图标可用 loadingIcon 定制。
面板模式 Cascader.Panel
从 5.10.0 起,Cascader.Panel 允许脱离触发器单独渲染选择面板,常被用在筛选表单、侧边抽屉或“内嵌级联”场景中。官方示例 panel.tsx 用法如下:
<Cascader.Panel options={options} onChange={onChange} disabled={disabled} />
<Cascader.Panel multiple options={options} onChange={onMultipleChange} disabled={disabled} />
<Cascader.Panel /> {/* 空数据,展示默认 Empty */}
从源码看,面板组件定义在 Panel.tsx,直接组合 @rc-component/cascader 的 Panel,并复用了组件级配置(useComponentConfig('cascader'))、禁用上下文(DisabledContext)、空态(notFoundContent)与展开/加载图标(useIcons),因此主题与图标策略与完整 Cascader 保持一致。Cascader.Panel 在 index.tsx 挂载为静态属性导出。
官方 API 还以
<code>形式提供调试/内部示例(如_InternalPanelDoNotUseOrYouWillBeFired的render-panel.tsx、菜单项省略号ellipsis-debug.tsx、Component Token 示例component-token.tsx),仅用于开发调试与内部快照,不建议在生产中使用。
方法与实例引用
Cascader 通过 ref 暴露两个实例方法:
| 名称 | 说明 |
|---|---|
blur() |
移除焦点 |
focus() |
获取焦点 |
对应类型 CascaderRef 定义于 index.tsx,方法最终透传给底层 RcCascader。
语义化 DOM:classNames / styles
自 5.25.0 起,Cascader 支持按语义结构精确命中内部 DOM,classNames 与 styles 均支持“对象”或“接收 { props } 返回对象的函数”两种形式(styles 的对象形式与组件顶层 style 自动合并到根节点)。可定制结构与类型声明见 CascaderSemanticType:
- 输入容器层级:
root、prefix、suffix、input、placeholder、content - 选中项/标签层级:
item、itemContent、itemRemove - 弹出层级:
popup(内含 Select 体系下的popup.root等子结构)
其中默认把 popup 展开映射到 popup.root(配置见 index.tsx),因此旧版 popupClassName/dropdownStyle 的迁移目标是 classNames.popup.root/styles.popup.root。交互预览示例为 _semantic.tsx(通过内部语义模板同时渲染单选与多选状态),完整风格覆盖场景可对照 style-class.tsx。
状态、布局与更多实战示例
官方文档以 <code> 列表沉淀了一批可直接运行的用例(位于 demo 目录,每例均带说明文件),按主题可分为:
- 基础与默认值:basic.tsx(最简单选)、default-value.tsx(受控/非受控初值);
- 交互行为:custom-trigger.tsx(自定义触发按钮)、hover.tsx(
expandTrigger="hover")、change-on-select.tsx(父级可选)、disabled-option.tsx(禁用项); - 多选:multiple.tsx、showCheckedStrategy.tsx;
- 数据与渲染:custom-render.tsx(
displayRender拼接展示列)、search.tsx、lazy.tsx、fields-name.tsx、[optionRender.tsx](对应optionRender,5.16.0); - 外观与浮层:size.tsx、variant.tsx、status.tsx、suffix.tsx、custom-dropdown.tsx(
popupRender追加面板底部内容)、placement.tsx; - 面板与样式定制:panel.tsx、style-class.tsx、component-token.tsx。
其中 placement 支持 bottomLeft/bottomRight/topLeft/topRight,默认 bottomLeft;在 RTL 场景下默认对齐自动切换为 bottomRight(index.tsx)。若浮层定位受 overflow: hidden 影响,官方建议通过 getPopupContainer 挂载到滚动容器内并将该容器设为 position: relative。
设计与主题定制:Design Token
与 Ant Design v5 全部组件一致,Cascader 的视觉样式由 Design Token 驱动,可通过 ConfigProvider 的 theme 统一调整颜色、圆角、字号、控制高度等基础 token,再经由 components: { Cascader: { ... } } 覆盖组件级 token。渲染侧,组件分别消费 Select 通用样式与自身样式(useSelectStyle + style/index.ts),并额外为面板场景加载 style/panel.ts,支持 CSS 变量(useCSSVarCls)与暗色模式变量(cssVarCls/hashId),见 index.tsx。当前仓库文档在 index.en-US.md 中以 <ComponentTokenTable component="Cascader"> 表格形式列出全部可用 token 名称及默认值,查阅时可对照中文版 index.zh-CN.md。
小结
Cascader 在 Ant Design 中承担“多级关联数据选择”的标准交互:options 树 + children/fieldNames 决定数据形状,value 路径数组 + onChange 定义状态流,showSearch、loadData、multiple、changeOnSelect 覆盖搜索、懒加载、多选与父级可选等进阶诉求,classNames/styles 语义结构与 Design Token 又提供了从精确 DOM 到全局主题的完整定制能力。实践时建议对照官方 demo 目录逐例运行验证行为,并以 index.en-US.md 的版本列为准处理 API 迁移与废弃。
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 StartedRust0627
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