列表搜索时怎么实现高亮匹配的关键词? Tr° 郭云 提问于 2026-03-11 17:48:24 阅读 55 交互 我在做一个用户列表的搜索功能,输入关键词后能过滤出匹配的项,但不知道怎么把匹配的文字高亮显示出来。试过直接用 innerHTML 插入带 <mark> 标签的字符串,但感觉不太安全,而且 Vue 里还报警告。 有没有更稳妥的做法?比如在渲染的时候动态包裹匹配部分?下面是我现在的过滤逻辑: const filteredUsers = users.filter(user => user.name.toLowerCase().includes(searchTerm.toLowerCase()) ); 列表搜索 我来解答 赞 6 收藏 分享 生成中... 手机扫码查看 复制链接 生成海报 反馈 发表解答 您需要先 登录/注册 才能发表解答 1 条解答 Air-珍珍 Lv1 这个问题我之前也踩过坑,说下我的做法。 最稳妥的方式是把匹配的文字拆分开,用 Vue 的 v-for 来分别渲染匹配和非匹配的部分,这样完全不需要 v-html,避免 XSS 风险: 先写个辅助函数,把文本按关键词拆成数组: function splitByKeyword(text, keyword) { if (!keyword) return [{ text, highlight: false }] const regex = new RegExp((${keyword}), 'gi') const parts = text.split(regex) return parts.map(part => ({ text: part, highlight: part.toLowerCase() === keyword.toLowerCase() })) } 然后在模板里这样用: :key="index" :class="{ 'highlight': part.highlight }"> {{ part.text }} 这样拆分后渲染,匹配到的文字会带上 highlight 类,没匹配的就是普通文本。 如果你非要用 v-html 也不是不行,但一定要先对原文本做 HTML 转义,再替换关键词: function highlightSafe(text, keyword) { if (!keyword) return text // 先转义 HTML 特殊字符 const escaped = text .replace(/&/g, '&') .replace(/ .replace(/>/g, '>') // 再替换关键词 const regex = new RegExp((${keyword}), 'gi') return escaped.replace(regex, '$1') } 不过说实话,第一种拆分渲染的方式更干净,不用担心 XSS 问题,也不会有 Vue 的警告。我现在项目里用的都是第一种。 回复 点赞 1 2026-03-11 18:02 加载更多 相关推荐 1 回答 57 浏览 搜索结果列表怎么实现动态高亮匹配关键词? 我在做搜索功能时,后端返回了结果列表,但想在前端把用户输入的关键词在结果中高亮显示。试过用 String.replace() 加 <mark> 标签,但发现如果关键词包含特殊字符(比如括号... Code°一诺 交互 2026-03-15 12:02:21 1 回答 40 浏览 搜索关键词高亮怎么在Vue里实现? 我在做搜索功能时想把匹配的关键词高亮显示,但直接用 v-html 插入带标签的字符串感觉不安全,而且试了下还会把整个结构搞乱。有没有更稳妥的办法? 比如我现在是这样写的: <template&g... 长孙子怡 交互 2026-03-31 12:57:13 1 回答 38 浏览 拼音搜索怎么匹配中文关键词? 我做了一个商品搜索功能,用户输入拼音比如 "shouji",希望能匹配到 "手机" 这类中文词,但不知道怎么实现。 试过用 pinyin 库把商品名转成拼音再比对,但性能太差,列表一长就卡。有没有更高... 春红 交互 2026-03-23 15:14:21 1 回答 87 浏览 搜索结果列表渲染后无法正确高亮关键词怎么办? 我用 JavaScript 动态渲染搜索结果,想把用户输入的关键词在结果中高亮显示,但试了好几种方法都不对。比如我把关键词替换成 <mark>关键词</mark>,结果页面上直... 码农瑞红 交互 2026-03-19 21:28:21 2 回答 166 浏览 搜索框输入时动态高亮列表项为什么会闪烁? 最近在做搜索组件,想实现输入时动态高亮匹配项。用JavaScript把匹配的关键词用<mark>标签包裹,但滚动列表时高亮会闪一下,而且原来的颜色样式被覆盖了。我试过给mark加!impo... Mr-慧慧 交互 2026-02-19 09:49:33 1 回答 72 浏览 拼音搜索怎么实现首字母匹配? 我在做一个联系人搜索功能,用户输入拼音首字母(比如“zj”)要能匹配到“张杰”这种名字,但不知道怎么高效处理。 试过把中文转成拼音再截取首字母,但性能很差,而且引入的库太大了。有没有轻量点的办法? 现... 雨妍 交互 2026-03-23 06:09:23 2 回答 56 浏览 Fuse.js 搜索结果高亮样式不生效是怎么回事? 我用 Fuse.js 做了个搜索功能,返回结果后想把匹配的关键词高亮显示,但加了 CSS 样式完全没反应。我试过给匹配词包上 <mark> 标签,也检查了类名,就是不生效。 这是我的高亮样... 司马艳丽 交互 2026-03-08 02:58:23 1 回答 37 浏览 热门搜索列表怎么实现自动滚动效果? 我在做搜索页的“热门搜索”模块,想让它像很多App那样自动横向滚动展示热门关键词。现在用的是一个普通的ul列表,试过用CSS的animation配合transform,但滚动到末尾就直接跳回开头,很突... 一庆庆 交互 2026-03-07 23:43:20 2 回答 34 浏览 列表搜索时输入框内容变化但列表没更新怎么办? 我在做商品列表的搜索功能,输入关键词后列表应该实时过滤,但不管怎么输,页面上的列表都没反应。明明数据变了,是不是哪里没触发更新? 我用的是原生JS操作DOM,监听了input事件,也重新渲染了列表,但... 成娟 交互 2026-03-07 15:51:19 1 回答 40 浏览 热门搜索列表怎么实现自动轮播切换? 我做了一个热门搜索的模块,想让它每隔3秒自动切换显示不同的关键词,但试了几次都没成功。用的是Vue3 + Composition API。 现在数据是静态的数组,渲染没问题,但加了setInterva... Prog.东宁 交互 2026-03-29 14:10:15
最稳妥的方式是把匹配的文字拆分开,用 Vue 的 v-for 来分别渲染匹配和非匹配的部分,这样完全不需要 v-html,避免 XSS 风险:
先写个辅助函数,把文本按关键词拆成数组:
然后在模板里这样用:
这样拆分后渲染,匹配到的文字会带上 highlight 类,没匹配的就是普通文本。
如果你非要用 v-html 也不是不行,但一定要先对原文本做 HTML 转义,再替换关键词:
不过说实话,第一种拆分渲染的方式更干净,不用担心 XSS 问题,也不会有 Vue 的警告。我现在项目里用的都是第一种。