Vue 3 中 computed 实现搜索高亮的核心是按关键词位置精准切片再拼接,而非简单字符串替换;需用 exec 循环获取匹配位置、slice 拆分文本、安全组装 mark 片段,并处理空关键词、XSS 防护与多词转义。

Vue 3 中用 computed 实现搜索高亮,关键不是“替换字符串”,而是把原始文本按关键词位置精准切片,再拼接带 的 HTML 片段。整个过程必须保持响应式纯净、避免 XSS、支持空关键词兜底。
核心思路:用 exec 遍历匹配位置,slice 拆分再组装
不能用 String.replace() 简单粗暴替换,否则无法控制高亮粒度,也难处理重叠或边界情况。正确做法是:
- 用
RegExp.exec()循环获取每个匹配项的index和[0](完整匹配)、[1](捕获组) - 用
str.slice(currentIndex, result.index)提取关键词前的普通文本 - 用
result[0]作为高亮部分,包裹... - 更新
currentIndex = result.index + result[0].length,继续下一轮 - 循环结束后,补上最后一段剩余文本(
str.slice(currentIndex))
computed 封装示例:返回安全的高亮片段数组
以下是一个可直接复用的计算属性写法(支持多关键词、大小写不敏感、空关键词防护):
v-for
- 原始文本未被当作 HTML 解析,只在
v-else分支中作为纯文本插入 -
是语义化内联标签,浏览器默认样式安全,不执行 JS - 若原始字段本身含用户输入的 HTML(如富文本),应在传入
rawText前先做基础转义(例如用DOMPurify.sanitize()或轻量函数转义为) - 多关键词时,把多个词用
|拼进正则,但需确保每个词都已转义,避免正则语法错误
性能优化建议(大文本/高频输入场景)
当 rawText 很长或 searchKeyword 频繁变化时,避免每次重算卡顿:
- 对搜索框使用
debounce(如lodash.debounce),延迟 200ms 触发关键词更新 - 限制高亮范围:只处理前 300 字符,用
text.slice(0, 300)入参,避免正则回溯爆炸 - 加缓存逻辑:仅当
rawText和searchKeyword同时未变时,复用上次结果(可用ref+JSON.stringify简单比对)
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










