如何使用react-highlight-words实现多关键词不同颜色高亮
React多关键词差异化高亮实现方案
方案1:基于现有react-highlight-words改造
不用替换你现在已经在用的依赖,改造成本最低,核心是利用组件支持自定义高亮标签的能力,给不同匹配关键词绑定对应样式。
- 先处理输入的多关键词
把原来的单关键词输入按分隔符拆成去重、过滤空值的数组,支持空格、中英文逗号/顿号/分号分隔:const keywordList = useMemo(() => { if (!textForSearch) return [] return Array.from(new Set( textForSearch.split(/[\s,,、;;]+/).filter(k => k.trim().length) )) }, [textForSearch]) - 预设关键词配色表
按顺序给关键词配置高亮样式,数量不够时自动循环取色:const keywordColorMap = [ { background: '#fff1b8', color: '#d46b08' }, { background: '#d9f7be', color: '#389e0d' }, { background: '#bae7ff', color: '#096dd9' }, { background: '#ffd6e7', color: '#c41d7f' }, { background: '#efdbff', color: '#531dab' } ] - 自定义高亮渲染标签
拿到当前高亮的文本内容,匹配其对应的关键词索引,绑定对应样式:const CustomHighlightMark = ({ children, ...rest }) => { const matchContent = children?.[0] ?? '' const currentKeywordIdx = keywordList.findIndex(k => matchContent.toLowerCase() === k.toLowerCase() ) const activeStyle = keywordColorMap[currentKeywordIdx % keywordColorMap.length] return ( <mark {...rest} style={{ padding: '0 2px', borderRadius: 2, margin: '0 1px', ...activeStyle }} > {children} </mark> ) } - 替换原有Highlighter配置
把单关键词数组替换为拆分后的多关键词列表,传入自定义高亮组件,保留原有转义配置避免特殊字符报错:{searchResults.map((result, idx) => { return ( <div key={`search-result-${idx}`}> <br /> <Highlighter searchWords={keywordList} autoEscape={true} caseSensitive={false} textToHighlight={finalResults[idx]} key={idx} highlightComponent={CustomHighlightMark} /> </div> ) })}
注意:自定义标签里的关键词大小写匹配逻辑,要和Highlighter的
caseSensitive配置保持一致,避免样式匹配错位。
方案2:无依赖原生实现
如果不想受第三方组件API限制,可以自己实现文本拆分高亮,逻辑完全可控,整体代码量也很小:
const MultiKeywordHighlighter = ({ text, keywords, colorMap }) => { if (!keywords.length) return <>{text}</> // 转义正则特殊字符 const escapeRegExp = (str) => str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&') // 生成全局匹配正则,每个关键词对应一个捕获组 const matchReg = new RegExp( keywords.map(k => `(${escapeRegExp(k)})`).join('|'), 'gi' ) // 拆分文本为普通片段、关键词片段 const textSegments = text.split(matchReg).filter(Boolean) return ( <> {textSegments.map((segment, idx) => { const keywordIdx = keywords.findIndex(k => k.toLowerCase() === segment.toLowerCase() ) // 非匹配内容直接渲染普通文本 if (keywordIdx === -1) return <span key={idx}>{segment}</span> // 匹配到的关键词加对应高亮样式 const highlightStyle = colorMap[keywordIdx % colorMap.length] return ( <mark key={idx} style={{ padding: '0 2px', borderRadius: 2, margin: '0 1px', ...highlightStyle }} > {segment} </mark> ) })} </> ) } // 使用方式 {searchResults.map((result, idx) => { return ( <div key={`search-result-${idx}`}> <br /> <MultiKeywordHighlighter text={finalResults[idx]} keywords={keywordList} colorMap={keywordColorMap} /> </div> ) })}
两种方案都支持同时匹配多个关键词,不同关键词自动分配不同高亮色,匹配逻辑和原有搜索逻辑完全兼容,不需要改动搜索/结果提取的相关代码。
内容的提问来源于stack exchange,提问作者cass
相关产品推荐
相关产品推荐

