Ant Design TreeSelect自定义filterTreeNode如何实现匹配节点高亮
Ant Design TreeSelect 自定义过滤后匹配不高亮问题解决方案
问题根因
Ant Design TreeSelect 的默认高亮逻辑与过滤逻辑互相独立:你自定义的 filterTreeNode 已经实现了特殊字符归一化后的匹配,可控制节点是否展示,但组件默认的高亮逻辑仍然使用用户输入的原始字符串,与节点的原始title做精确子串匹配,两者逻辑不一致就会出现过滤命中但高亮不生效的问题。
修复步骤
- 第一步:实现统一的字符归一化工具函数,对输入内容和节点title做相同规则的格式化,消除特殊字符差异
// 去除字符重音标记、统一转为小写 const normalizeString = (str) => { return str.normalize("NFD").replace(/[\u0300-\u036f]/g, "").toLowerCase(); };
- 第二步:自定义
filterTreeNode过滤逻辑,移除原有的treeNodeFilterProp="title"配置,使用归一化后的字符串做匹配判断
const filterTreeNode = (inputValue, treeNode) => { if (!inputValue) return true; const normalizedInput = normalizeString(inputValue); const normalizedTitle = normalizeString(treeNode.title); return normalizedTitle.includes(normalizedInput); };
- 第三步:通过
treeNodeTitleRender自定义节点标题渲染,自行实现归一化后的匹配高亮逻辑,直接复用Ant Design默认的高亮类名保持样式一致
const treeNodeTitleRender = (node, inputValue) => { // 无输入时直接返回原始标题 if (!inputValue) return node.title; const normalizedTitle = normalizeString(node.title); const normalizedInput = normalizeString(inputValue); const matchStartIndex = normalizedTitle.indexOf(normalizedInput); // 无匹配时直接返回原始标题 if (matchStartIndex === -1) return node.title; // 按匹配位置切分原始标题,包裹高亮样式 const beforeMatch = node.title.slice(0, matchStartIndex); const matchContent = node.title.slice(matchStartIndex, matchStartIndex + normalizedInput.length); const afterMatch = node.title.slice(matchStartIndex + normalizedInput.length); return ( <span> {beforeMatch} <span className="ant-select-tree-node-content-wrapper-highlight">{matchContent}</span> {afterMatch} </span> ); };
- 第四步:将自定义逻辑注入TreeSelect组件
<TreeSelect filterTreeNode={filterTreeNode} treeNodeTitleRender={treeNodeTitleRender} // 其他原有配置(treeData、placeholder、onChange等)保持不变 />
内容的提问来源于stack exchange,提问作者Jan Krupiński
相关产品推荐
相关产品推荐

