首页
/ Ant Design Cascader 选项搜索(showSearch):从搜索 Demo 到源码级实现解析

Ant Design Cascader 选项搜索(showSearch):从搜索 Demo 到源码级实现解析

2026-09-06 18:28:40作者:乔或婵

Cascader 是 Ant Design 中用于处理层级数据(如省市区、组织机构、分类树)选择的组件。默认交互是逐级点击菜单完成选择,但当选项层级深、数据量大时,逐级翻找并不高效。本篇文章以仓库中 components/cascader/demo/search.md 的「搜索」示例(对应 search.tsx)为切入点,系统讲解 Cascader[showSearch] 的开启方式、完整配置参数、自定义筛选逻辑与关键词高亮的底层实现,帮助你为省市区、多级菜单等场景快速落地「即输即搜、一键直达」的搜索体验。

搜索 Demo 概览:直接在输入框中搜索并选择

search.md 中对该示例的描述非常精炼:

可以直接搜索选项并选择。(Search and select options directly.)

即:在输入框中直接输入关键词,选项会被实时过滤,高亮命中的部分后直接在结果列表中点选,最终回填为完整的级联路径值。

该示例同时包含一句关键提示:

Cascader[showSearch] 暂不支持服务端搜索(Now, Cascader[showSearch] doesn't support search on server)。

也就是说,Cascader 的内置搜索是纯前端的本地过滤,作用于 options 中已加载的数据。当数据量极大、需要远程异步按关键词拉取候选时,不应依赖 showSearch,而应从数据源层面(例如在 lazy.md 展示的动态加载方向)自行设计;官方讨论记录见 ant-design issue #5547。下文的源码分析会进一步印证这一设计边界。

如何开启搜索:Demo 的完整可运行代码

开启方式是把 showSearch 设为 true 或配置对象。为便于理解,这里展开 search.tsx 的核心实现:

import React from 'react';
import { Cascader } from 'antd';
import type { CascaderProps, GetProp } from 'antd';

type DefaultOptionType = GetProp<CascaderProps, 'options'>[number];

interface Option {
  value: string;
  label: string;
  children?: Option[];
  disabled?: boolean;
}

const options: Option[] = [
  {
    value: 'zhejiang',
    label: 'Zhejiang',
    children: [
      {
        value: 'hangzhou',
        label: 'Hangzhou',
        children: [
          { value: 'xihu', label: 'West Lake' },
          { value: 'xiasha', label: 'Xia Sha', disabled: true },
        ],
      },
    ],
  },
  {
    value: 'jiangsu',
    label: 'Jiangsu',
    children: [
      {
        value: 'nanjing',
        label: 'Nanjing',
        children: [{ value: 'zhonghuamen', label: 'Zhong Hua men' }],
      },
    ],
  },
];

const onChange: CascaderProps<Option>['onChange'] = (value, selectedOptions) => {
  console.log(value, selectedOptions);
};

// 自定义过滤规则:只要路径上任意一级 label 命中输入值即保留
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) }}
  />
);

export default App;

代码要点:

  • 数据是典型的三级结构(Zhejiang → Hangzhou → West Lake / Xia Sha),其中 Xia Sha 被标记为 disabled,用于演示被禁用的叶子节点不会出现在搜索结果里可被选中的状态(搜索测试中也有对 ant-cascader-menu-item-disabled 的断言)。
  • showSearch 以对象形式传入,覆盖了 filter(过滤规则)与 onSearch(监听输入)两个能力。注意 onChange 的回调参数 value 是完整路径数组(如 ['zhejiang', 'hangzhou', 'xihu']),selectedOptions 则是命中的完整选项链。
  • 默认过滤是大小写不敏感的包含匹配,示例中刻意对 inputValuelabel 都执行 toLowerCase() 再判断。

showSearch 完整配置项详解

根据 Cascader API 文档(英文版见 index.en-US.md),showSearch 可接受 boolean 或如下配置对象。当传入 true 时相当于启用一套内置默认行为(详见下文「合并逻辑」)。

参数 说明 类型 默认值 版本
autoClearSearchValue 选中项后是否清空搜索框,仅在 multipletrue 时有效 boolean true 5.9.0
filter 接收 (inputValue, path),当 path 符合筛选条件时返回 true 保留,否则排除 (inputValue, path) => boolean - -
limit 搜索结果展示数量上限 number | false 50 -
matchInputWidth 搜索结果列表是否与输入框同宽 boolean true -
render 用于渲染过滤后的选项 (inputValue, path) => ReactNode - -
sort 对过滤后的选项排序 (a, b, inputValue) - -
searchValue 受控的搜索值,需与 showSearch 配合 string - 4.17.0
onSearch 监听搜索输入,回调返回输入的值 (search: string) => void - 4.17.0
searchIcon 自定义搜索图标 ReactNode - 6.3.0

在组件顶层(而非 showSearch 对象内)也出现过 searchValueonSearch 两个属性,它们在文档中已被标记为 deprecated(删除线,官方建议改用上述 showSearch 对象内的同名字段。

几个值得注意的默认值与行为:

  • limit 默认 50:当命中结果很多时仅展示前 50 条,可通过 limit: false 关闭数量上限,或调大数值。仓库测试中通过 limit: 1 断言结果仅保留 1 条,验证了该字段生效路径(index.test.tsx)。
  • filter 语义是按「路径」过滤:传入的第二个参数是从根到当前节点的整条 path,因此可以实现「只要路径上任意一级匹配就展示该分支」的级联搜索,这正是 Demo 中 path.some(...) 写法存在的意义——例如输入 West 也能定位到 Zhejiang / Hangzhou / West Lake
  • 无命中结果:会展示 notFoundContent(默认「暂无数据」,即 Empty 空状态)。测试覆盖了自定义文案与 notFoundContent={null} 隐藏空态两种场景(index.test.tsx)。

源码侧看实现:搜索如何与 Cascader 组装

showSearch 的合并逻辑

components/cascader/index.tsx 中,组件会对 showSearch 做一次归一化处理:

const mergedShowSearch = React.useMemo(() => {
  if (!showSearch) {
    return showSearch;
  }

  let searchConfig: SearchConfig = {
    render: defaultSearchRender,
  };

  if (isPlainObject(showSearch)) {
    searchConfig = { ...searchConfig, ...showSearch };
  }

  return searchConfig;
}, [showSearch]);

这段代码说明三件事:

  1. 未开启 showSearch 时原样透传(不产生任何搜索能力);
  2. 只要开启,Ant Design 就会注入一个默认的 render 实现 defaultSearchRender,保证即使你只写 showSearch,结果渲染也带有关键词高亮;
  3. 传入对象时通过浅合并覆盖默认项,因此 filterrenderlimitsortsearchValueonSearchsearchIcon 都是可定制的。

合并后的配置最终透传给底层实现 @rc-component/cascaderRcCascader 组件(见 index.tsx),即搜索过滤、输入监听等核心机制复用 rc 生态的 Select 系实现。

默认结果渲染与关键词高亮

默认 renderdefaultSearchRenderindex.tsx),它负责把命中的完整路径渲染为 标签 / 父级 / 命中项 的分段形式,并且调用 highlightKeyword 对命中片段做高亮包装。

highlightKeywordindex.tsx)的实现思路是把原文按关键词小写拆分后重组,命中片段用带类名 ${prefixCls}-menu-item-keyword<span> 包裹,从而在搜索结果中呈现出黄色关键词高亮效果。搜索相关快照测试(如 should highlight keyword and filter when search in Cascader)正是围绕该高亮结果展开的(index.test.tsx)。

搜索图标

搜索模式下输入框左侧会展示放大镜图标,可通过 showSearch.searchIcon 或 ConfigProvider 全局配置(searchIcon token 于 6.4.0 支持组件级配置)自定义。在源码中,当 showSearch 为对象时,其 searchIcon 会被提取并并入 Select 图标逻辑:searchIcon: isPlainObject(showSearch) ? showSearch.searchIcon : undefinedindex.tsx)。

与多选、动态加载的配合边界

源码注释与 API 文档给出两条重要约束,与 search.md 的「不支持服务端搜索」提示互为补充:

  • loadData(动态加载)无法与 showSearch 同时使用(见 index.zh-CN.md API 表),原因在于远程数据在键入时尚未全部就绪,本地过滤无从谈起;
  • 搜索输入对单选、多选(multiple)场景都生效,但 autoClearSearchValue 只在 multipletrue 时有意义——单选选中后输入框自然关闭,多选场景才需要决定是否保留当前搜索词以便继续追加选择。

搜索行为的可验证细节

仓库测试为搜索行为提供了多组可验证的断言(components/cascader/tests/index.test.tsx),可据此确认实际交互:

  • 键入即触发过滤与展开:向输入框输入内容后浮层展开并展示过滤结果;
  • 退格清空关键词后关闭浮层backspace 清空后下拉自动收起;
  • 点击清除按钮会同步清空搜索词:输入搜索词后点击清除,输入框 value 归空;
  • options 变化时结果同步更新:rerender 新的 options 后,过滤出的菜单项数量随之变化;
  • 方向键下 + 回车可直接选中:搜索命中后可直接用键盘选中,无需回到层级菜单;
  • 禁用项正确显示禁用态:命中的禁用节点带有 -disabled 类名,不可选中。

这些测试与 demo 一同证明:开启 showSearch 后,Cascader 的体验向普通 Select 的搜索对齐——输入、过滤、高亮、键盘操作与空态提示都已内置。Demo 本身也通过 demo.test.tsxcomponents/cascader/tests/demo.test.tsx)在测试套件中持续运行,保证示例代码可维护、可运行。

小结与实践建议

围绕 components/cascader/demo/search.md 所对应的「搜索」Demo,可以得出如下可直接落地的结论:

  1. 小到中型、已完整加载的级联数据:直接 showSearch,配合自定义 filter(按 path 路径匹配)即可获得带高亮的级联搜索;
  2. 命中结果可能很多:用 limit 控制展示条数,避免性能与视觉负担;
  3. 需要定制结果文案或排序:通过 rendersort 实现,默认值已包含关键词高亮;
  4. 多选场景:合理利用 autoClearSearchValue 决定选中后是否保留关键词;
  5. 海量数据或远程搜索诉求showSearch 是纯前端过滤,不支持服务端搜索,且与 loadData 互斥——应转向自行实现远程候选源 + 自定义下拉内容(popupRender/optionRender)的路线。

把握住「本地路径过滤 + 关键词高亮 + 前端数据源」这一定位,Cascader 的搜索能力即可在省市区选择、组织树导航、多级类目筛选等典型场景中发挥出最大价值。

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