首页
/ Ant Design Cascader 级联选择器完全指南:API 解析与源码级实践

Ant Design Cascader 级联选择器完全指南:API 解析与源码级实践

2026-09-06 18:35:45作者:侯霆垣

本指南基于 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 与其 BaseOptionTypeDefaultOptionTypeSearchConfig 等类型,同时复用了 Select 的样式系统(useSelectStylemergedBuiltinPlacements)与图标工具(useSelectIconsusePopupRenderuseShowArrow),因此它在外观与行为上(搜索列表、悬浮透明度、命中高亮等)与 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} />valuedefaultValue 的类型为 string[] | number[],即每一级取值的路径序列。完整可运行源码见 basic.tsx

核心 API 全解析

官方文档的 API 表是理解组件行为的权威索引,以下保留全部字段,并补充取值语义与版本说明。通用属性(如 idclassNamearia 相关等)参照 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 自定义 labelvaluechildren 的字段名 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),映射关系一目了然:

  • dropdownClassNameclassNames.popup.root
  • dropdownStylestyles.popup.root
  • dropdownRenderpopupRender
  • dropdownMenuColumnStyle / popupMenuColumnStylestyles.popup.listItem
  • onDropdownVisibleChange / onPopupVisibleChangeonOpenChange
  • borderedvariant
  • showArrow → 通过 suffixIcon={null} 隐藏箭头

实现上,这些迁移在 index.tsx 统一收敛:mergedPopupRender = usePopupRender(popupRender || dropdownRender)mergedPopupStyle = { ...mergedStyles.popup.root, ...dropdownStyle }mergedOnOpenChange 依次回退取新 API,做到新旧属性兼容过渡。

多选与回显策略

multiple 开启后选项前出现 Checkbox,勾选支持父子级联。回显由 showCheckedStrategy 控制,它引用自 RcCascader 暴露的常量 SHOW_CHILD / SHOW_PARENTindex.tsx),并被挂到组件静态属性 Cascader.SHOW_PARENT / Cascader.SHOW_CHILDindex.tsx)。示例可对照 showCheckedStrategy.tsx:默认值里同时勾选了 bamboo/little 下三个叶子时,SHOW_CHILD 回显三片叶子标签,SHOW_PARENT 只回显父路径标签;标签溢出时可用 maxTagCount="responsive" 响应式折叠。

多选基础用法见 multiple.tsx,其 Option 额外演示了 disableCheckbox 字段(禁用单个节点的勾选框但不禁用浏览)。

形态:size、variant、status 与前后缀

  • sizelarge / medium(默认)/ small,源码在渲染时追加 ${prefixCls}-lg / ${prefixCls}-sm 类并受 ConfigProvider componentSize 与 Space.Compact 上下文合并(index.tsx)。
  • variantoutlined / filled / borderless / underlined,通过 useVariant('cascader', customVariant, bordered) 与表单上下文联动(index.tsx),与 Input、Select 视觉统一。
  • statuserror / warning,可配合 Form.Item validateStatus 自动透传;组件通过 FormItemInputContext 读取表单态并合并 getStatusClassNamesindex.tsx)。
  • prefix / suffixIcon / clearIcon / removeIcon / loadingIcon / expandIcon / searchIcon:分别定制前缀、下拉箭头、清除、移除、加载、展开、搜索图标;expandIconloadingIcon 等支持在 ConfigProvider 组件级配置中统一注入(源码通过 useComponentConfig('cascader') 与 hooks/useIcons.ts 完成合并)。对应示例见 suffix.tsxvariant.tsxstatus.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) }}
  />
);

在默认情况下(showSearchtrue 或对象但未提供 render),命中结果按完整路径以 / 连接展示,关键词会被包裹进 ${prefixCls}-menu-item-keyword 高亮节点;这一逻辑实现在组件内的 highlightKeyworddefaultSearchRenderindex.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/onChangestring[] | number[] 路径语义对应;
  • labelReactNode,支持富文本节点,例如带图标的层级名称;
  • 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: falseloadData(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/cascaderPanel,并复用了组件级配置(useComponentConfig('cascader'))、禁用上下文(DisabledContext)、空态(notFoundContent)与展开/加载图标(useIcons),因此主题与图标策略与完整 Cascader 保持一致。Cascader.Panelindex.tsx 挂载为静态属性导出。

官方 API 还以 <code> 形式提供调试/内部示例(如 _InternalPanelDoNotUseOrYouWillBeFiredrender-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,classNamesstyles 均支持“对象”或“接收 { props } 返回对象的函数”两种形式(styles 的对象形式与组件顶层 style 自动合并到根节点)。可定制结构与类型声明见 CascaderSemanticType

  • 输入容器层级:rootprefixsuffixinputplaceholdercontent
  • 选中项/标签层级:itemitemContentitemRemove
  • 弹出层级:popup(内含 Select 体系下的 popup.root 等子结构)

其中默认把 popup 展开映射到 popup.root(配置见 index.tsx),因此旧版 popupClassName/dropdownStyle 的迁移目标是 classNames.popup.root/styles.popup.root。交互预览示例为 _semantic.tsx(通过内部语义模板同时渲染单选与多选状态),完整风格覆盖场景可对照 style-class.tsx

状态、布局与更多实战示例

官方文档以 <code> 列表沉淀了一批可直接运行的用例(位于 demo 目录,每例均带说明文件),按主题可分为:

其中 placement 支持 bottomLeft/bottomRight/topLeft/topRight,默认 bottomLeft;在 RTL 场景下默认对齐自动切换为 bottomRightindex.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 定义状态流,showSearchloadDatamultiplechangeOnSelect 覆盖搜索、懒加载、多选与父级可选等进阶诉求,classNames/styles 语义结构与 Design Token 又提供了从精确 DOM 到全局主题的完整定制能力。实践时建议对照官方 demo 目录逐例运行验证行为,并以 index.en-US.md 的版本列为准处理 API 迁移与废弃。

登录后查看全文
热门项目推荐
相关项目推荐