
ant-design AutoComplete「查询模式 - 确定类目」实现解析用 options 构建分组式搜索建议【免费下载链接】ant-designAn enterprise-class UI design language and React UI library项目地址: https://gitcode.com/GitHub_Trending/an/ant-design本文基于 ant-design 仓库中的示例 certain-category配套说明见 certain-category.md讲解设计规范中「查询模式确定类目」这一搜索建议形态的完整落地方式。读完后你能掌握如何用嵌套options结构渲染「类目分组 自定义选项」的下拉建议列表、如何用语义化classNames与设计 Token 定制下拉面板样式以及该模式与「不确定类目」模式在实现上的本质差异。1. 什么是「查询模式确定类目」ant-design 的设计规范 交互规范 - 即时反应 中定义了「查询模式」用户输入时下拉列表随着输入的关键词显示匹配项。根据查询结果分类数量的多少它分为两类确定类目用户所查询的关键词只会出现在已知且固定的几种类目中例如「话题」「问题」「文章」这 3 类。下拉面板中的类目结构在渲染前就是确定的不确定类目关键词可能命中的类目数量不确定结果通常需要实时请求类目数量随查询动态变化。「确定类目」的典型场景是站内搜索、内容检索站点的栏目结构是预先定义的如 Libraries / Solutions / Articles只需把数据按类目分组后一次性交给组件由组件在本地完成过滤即可不需要每次输入都发起异步请求。本文的示例正是这一模式的官方参考实现。2. 示例代码完整解读示例源码位于 certain-category.tsx完整代码如下import React from react; import { UserOutlined } from ant-design/icons; import { AutoComplete, Flex, Input } from antd; import { createStyles } from antd-style; const useStyles createStyles((props) { const { css, prefixCls, cssVar } props; return { categorySearch: css .${prefixCls}-select-dropdown-menu-item-group-title { color: #666; font-weight: ${cssVar.fontWeightStrong}; } .${prefixCls}-select-dropdown-menu-item-group { border-bottom: ${cssVar.lineWidth} ${cssVar.lineType} #f6f6f6; } .${prefixCls}-select-dropdown-menu-item { padding-inline-start: ${cssVar.padding}; } .${prefixCls}-select-dropdown-menu-item.show-all { text-align: center; cursor: default; } .${prefixCls}-select-dropdown-menu { max-height: 300px; } , }; }); const Title: React.FCReadonly{ title?: string } (props) ( Flex aligncenter justifyspace-between {props.title} a hrefhttps://www.google.com/search?qantd target_blank relnoopener noreferrer more /a /Flex ); const renderItem (title: string, count: number) ({ value: title, label: ( Flex aligncenter justifyspace-between {title} span UserOutlined / {count} /span /Flex ), }); const options [ { label: Title titleLibraries /, options: [renderItem(AntDesign, 10000), renderItem(AntDesign UI, 10600)], }, { label: Title titleSolutions /, options: [renderItem(AntDesign UI FAQ, 60100), renderItem(AntDesign FAQ, 30010)], }, { label: Title titleArticles /, options: [renderItem(AntDesign design language, 100000)], }, ]; const App: React.FC () { const { styles } useStyles(); return ( AutoComplete classNames{{ popup: { root: styles.categorySearch } }} popupMatchSelectWidth{500} style{{ width: 250 }} options{options} Input.Search sizelarge placeholderinput here / /AutoComplete ); }; export default App;代码可以分为四个要点来理解。2.1 类目分组嵌套的options结构「确定类目」的关键在于options的两层嵌套const options [ { label: Title titleLibraries /, // 第一层 label类目分组标题 options: [ // 第一层 options该类目下的条目 renderItem(AntDesign, 10000), renderItem(AntDesign UI, 10600), ], }, // ... Solutions / Articles 两组 ];每一层的数据形状一致{ label, value?, options? }外层项没有value、只有label和options表示这是一个分组内层项有value和label表示这是可选中的条目。AutoComplete 底层复用了 Select 的选项体系其fieldNames默认值正是{ label: label, value: value, options: options, groupLabel: label }见 Select 文档 中fieldNames一行即「含options字段的项按label渲染为分组标题」这与 JSX 中用OptGroup分组见 optgroup 示例是同一机制的数据化写法官方也注明数据化配置「相比 jsx 定义会获得更好的渲染性能」。分组的标题本身是任意的 ReactNode。示例中的Title组件用Flex布局把类目名与一个「more」链接排成两端对齐的一行模拟真实站点中「点击 more 跳转该栏目全部结果」的交互。2.2 条目内容label与value分离renderItem展示了options数据化配置的核心用法——value负责回填与取值label负责展示const renderItem (title: string, count: number) ({ value: title, // 选中后写入输入框、传给 onSelect/onChange 的值 label: ( Flex aligncenter justifyspace-between {title} span UserOutlined / {count} // 条目右侧展示「热度/人数」等元信息 /span /Flex ), });label可以是任意 ReactNode因此可以在单条建议中同时呈现标题与元信息示例中是UserOutlined图标加数量。选中条目后输入框回填的是value纯文本而不是这段带图标的节点这正是label/value分离的意义。2.3 下拉面板定制语义化classNames.popup.root 设计 Token示例使用antd-style的createStyles注入下拉面板样式并通过classNames{{ popup: { root: styles.categorySearch } }}挂到 AutoComplete 的popup.root语义结构上。这是 5.x 推荐的下拉样式入口旧的dropdownClassName/popupClassName已废弃见 AutoComplete 源码中的弃用提示。样式中直接引用了 Select 内部的下拉 DOM 类名配合prefixCls与cssVar设计 Token保证主题兼容目标选择器定制内容依赖的 Token.ant-select-dropdown-menu-item-group-title分组标题灰色加粗fontWeightStrong.ant-select-dropdown-menu-item-group分组间底部分隔线lineWidth、lineType.ant-select-dropdown-menu-item条目内边距营造层级缩进padding.ant-select-dropdown-menu下拉最大高度300px超出滚动-popupMatchSelectWidth{500}则让下拉面板固定 500px 宽宽于 250px 的输入框——「确定类目」面板通常信息量较大分组标题 条目元信息面板需要更宽的展示空间这是该示例的又一特征。2.4 自定义输入框children传入Input.SearchAutoComplete ... Input.Search sizelarge placeholderinput here / /AutoCompleteAutoComplete 允许把任意合法输入组件作为children传入。从源码结构看AutoComplete.tsx组件会检查children当且仅当它是唯一一个非Option/OptGroup的合法元素时才会被认定为自定义输入框并通过内部 APIgetInputElement注入给底层 Select 替换默认Input /。这意味着传入Input.Search后输入框自动带上搜索图标与大尺寸样式无需额外配置由于样式改由子组件自己控制此时不要再给 AutoComplete 设置size否则开发环境下会收到usage警告源码 AutoComplete.tsx#L179-L186 中有对应的devUseWarning。3. 源码佐证AutoComplete 如何承接这套 options理解「确定类目」为何能零请求工作需要看 AutoComplete 实现 的两个事实AutoComplete 本质是 Select 的组合框模式。组件最终渲染的是一个内部Select并固定mode{Select.SECRET_COMBOBOX_MODE_DO_NOT_USE}AutoComplete.tsx#L277。因此 Select 的全部选项能力——options数据化、分组、fieldNames、optionFilterProp——在 AutoComplete 中原样可用「分组下拉」不需要任何额外开关。本地过滤是默认行为。示例没有传任何搜索回调说明默认配置下组件会在输入时自动对options做本地过滤输入关键词时三个类目分组中与之匹配的条目保留在面板中。这正是「确定类目」模式的实现基线——类目结构静态确定过滤在客户端完成。另外注意AutoCompleteProps的类型定义AutoComplete.tsx#L56-L97通过Omit移除了loading、mode、labelInValue等组合框不适用的属性并新增了status、showSearch支持filterOption/onSearch/searchIcon子配置等字段dataSource属性已标记deprecated官方要求统一使用options。4. 对照与「不确定类目」模式的实现差异同目录下的 uncertain-category.tsx 是「不确定类目」的参考实现两者差异一目了然维度确定类目本文不确定类目类目结构静态、预先分组渲染前即确定动态随查询结果返回options来源模块级常量直接传入useState管理由showSearch{{ onSearch: handleSearch }}在每次输入时更新可为空数组数据来源本地数据无异步请求通常对应真实搜索接口需自行处理请求逻辑面板宽度popupMatchSelectWidth{500}宽于输入框popupMatchSelectWidth{252}贴近输入框即「确定类目」 静态嵌套options 本地过滤「不确定类目」onSearch回调 受控options。选型依据是规范中的那句划分如果关键词只会出现在已知固定的类目中就用前者如果命中类目数量不确定就用后者其思路与 options 自定义选项示例 中的邮箱后缀补全一致——onSearch里根据输入拼装候选项。5. 关键参数速查与注意事项结合 AutoComplete 官方 API本示例涉及的参数与相关注意点参数说明示例取值options数据化配置选项内容{ label, value }[]支持嵌套分组两层嵌套的类目结构children自定义输入框传入Input.SearchInput.Search sizelarge /classNames.popup.root下拉面板根节点样式入口替代已废弃的popupClassNamestyles.categorySearchpopupMatchSelectWidth下拉面板宽度数字时直接取像素值500style输入框根节点宽度{ width: 250 }onSelect/onChange选中条目 / 值变化回调示例中未用实际业务中用于提交搜索注意事项均来自仓库文档与源码受控状态下不要只用onSearch管理输入值。官方 FAQindex.zh-CN.md明确请使用onChange进行受控管理onSearch触发于搜索输入时机与onChange不同且点击选项不会触发onSearch。这也是受控输入无法输入中文的常见根因。旧属性迁移dataSource→options、dropdownClassName/popupClassName→classNames.popup.root、dropdownRender→popupRender、onDropdownVisibleChange→onOpenChange、dropdownMatchSelectWidth→popupMatchSelectWidth。源码中保留了对这些旧属性的合并兼容与开发环境弃用警告AutoComplete.tsx#L128-L130。虚拟滚动popupMatchSelectWidth传false时会关闭虚拟滚动见 API 表示例中下拉设置了max-height: 300px条目较多时可依赖默认虚拟滚动virtual默认true保持性能。6. 小结「确定类目」模式的工程要点可以概括为三步把类目结构组织成嵌套options外层{ label: 分组标题, options: 条目[] }内层{ value, label }分组标题与条目内容均可使用自定义 ReactNode依赖组件默认的本地过滤即可实现「输入即筛选」无需请求用classNames.popup.root挂接基于设计 Token 的下拉样式用popupMatchSelectWidth放宽面板用children注入Input.Search等自定义输入框。参考文件certain-category 示例源码、不确定类目对照示例、AutoComplete 实现、AutoComplete 文档、交互规范 - 查询模式。【免费下载链接】ant-designAn enterprise-class UI design language and React UI library项目地址: https://gitcode.com/GitHub_Trending/an/ant-design创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考