用computed实现长列表实时关键字高亮过滤,关键在于将匹配逻辑与渲染准备分离:计算属性生成带html标签的安全高亮片段,模板用v-html渲染,兼顾性能、安全与响应式联动。

用 computed 实现长列表的实时关键字高亮过滤,关键在于把“匹配逻辑”和“渲染准备”拆开:计算属性只负责生成带 HTML 标签的安全高亮片段,模板里用 v-html 渲染,同时兼顾性能、安全与响应式联动。
一、基础结构:定义响应式关键词与原始数据
搜索关键词必须是响应式数据,否则 computed 无法追踪变化。原始列表也需是响应式(ref 或 reactive 包裹):
- Composition API 中用 ref('') 声明
searchKey - 商品列表用 ref([]) 或 reactive([]),确保 Vue 能监听其变化
- 避免直接修改原数组——filter 返回新数组,保持不可变性
二、高亮计算属性:动态正则 + 安全包裹
核心是写一个计算属性,对每个 item 的目标字段(如 name、desc)生成带 <span class="highlight"></span> 的高亮字符串:
- 先判断
searchKey.value.trim()是否为空,空则直接返回原文本,防止new RegExp('', 'gi')报错 - 用
new RegExp(searchKey.value.replace(/[.*+?^${}()|[]\]/g, '\$&'), 'gi')动态构造正则,转义特殊字符(如+、.) - 用
String.prototype.replace()的回调函数精准包裹匹配内容,不破坏原始结构 - 返回新对象数组,每个 item 新增
highlightedName字段,不修改原始数据
三、模板中安全使用 v-html
高亮内容必须通过 v-html 渲染,但仅限可信字段:
- 只在明确来自计算属性的字段上用:
v-html="item.highlightedName" - 若原始字段含用户输入(如评论),先做 HTML 实体转义(
→ <code><),再高亮,防 XSS - 禁止让关键词控制 class 名、style 属性或插入任意标签;
class="highlight"写死在 span 里即可 - 富文本字段(如含
)应先用
textContent提取纯文本,再高亮
四、长列表性能优化建议
列表量大或字段过长时,需主动控频和截断:
- 输入防抖放在事件层(如
@input中用lodash.debounce更新searchKey),不是在 computed 里做 - 单字段文本超 200 字可先
slice(0, 200) + '...',再高亮,避免正则回溯卡顿 - 多字段高亮(title + desc + author)就为每个字段单独定义计算字段:
highlightedTitle、highlightedDesc - computed 天然缓存:关键词没变、原始数据没变,就不会重算,无需额外 memoize
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










