列表搜索时怎么实现高亮匹配的关键词? Tr° 郭云 提问于 2026-03-11 17:48:24 阅读 9 交互 我在做一个用户列表的搜索功能,输入关键词后能过滤出匹配的项,但不知道怎么把匹配的文字高亮显示出来。试过直接用 innerHTML 插入带 <mark> 标签的字符串,但感觉不太安全,而且 Vue 里还报警告。 有没有更稳妥的做法?比如在渲染的时候动态包裹匹配部分?下面是我现在的过滤逻辑: const filteredUsers = users.filter(user => user.name.toLowerCase().includes(searchTerm.toLowerCase()) ); 列表搜索 我来解答 赞 1 收藏 分享 生成中... 手机扫码查看 复制链接 生成海报 反馈 发表解答 您需要先 登录/注册 才能发表解答 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 加载更多 相关推荐 0 回答 5 浏览 搜索结果列表怎么实现动态高亮匹配关键词? 我在做搜索功能时,后端返回了结果列表,但想在前端把用户输入的关键词在结果中高亮显示。试过用 String.replace() 加 <mark> 标签,但发现如果关键词包含特殊字符(比如括号... Code°一诺 交互 2026-03-15 12:02:21 2 回答 152 浏览 搜索框输入时动态高亮列表项为什么会闪烁? 最近在做搜索组件,想实现输入时动态高亮匹配项。用JavaScript把匹配的关键词用<mark>标签包裹,但滚动列表时高亮会闪一下,而且原来的颜色样式被覆盖了。我试过给mark加!impo... Mr-慧慧 交互 2026-02-19 09:49:33 1 回答 25 浏览 Fuse.js 搜索结果高亮样式不生效是怎么回事? 我用 Fuse.js 做了个搜索功能,返回结果后想把匹配的关键词高亮显示,但加了 CSS 样式完全没反应。我试过给匹配词包上 <mark> 标签,也检查了类名,就是不生效。 这是我的高亮样... 司马艳丽 交互 2026-03-08 02:58:23 1 回答 16 浏览 热门搜索列表怎么实现自动滚动效果? 我在做搜索页的“热门搜索”模块,想让它像很多App那样自动横向滚动展示热门关键词。现在用的是一个普通的ul列表,试过用CSS的animation配合transform,但滚动到末尾就直接跳回开头,很突... 一庆庆 交互 2026-03-07 23:43:20 1 回答 20 浏览 列表搜索时输入框内容变化但列表没更新怎么办? 我在做商品列表的搜索功能,输入关键词后列表应该实时过滤,但不管怎么输,页面上的列表都没反应。明明数据变了,是不是哪里没触发更新? 我用的是原生JS操作DOM,监听了input事件,也重新渲染了列表,但... 成娟 交互 2026-03-07 15:51:19 1 回答 83 浏览 表单搜索时输入框内容清空后怎么自动重新加载全部数据? 我在做一个带搜索功能的用户列表页面,输入关键词能正常过滤,但清空输入框后列表没变回全部数据,还是显示上次搜索的结果,这咋办? 我试过监听 input 事件,但清空的时候好像没触发重新获取原始数据的逻辑... UP主~雯清 交互 2026-03-13 11:52:20 1 回答 230 浏览 iView Select选择器怎么实现远程搜索并保持已选项不被清空? 我在用 iView 的 Select 做一个带远程搜索的下拉框,用户选了几个选项后,再输入关键词搜索,结果之前选中的项全没了。明明文档里说 multiple 模式下应该保留已选项啊? 我试过在 on-... Mr.淑涵 组件 2026-03-11 10:38:26 1 回答 9 浏览 ElasticSearch 搜索结果高亮怎么不生效? 我在用 ElasticSearch 做商品搜索,加了 highlight 配置但返回结果里没有高亮字段。请求体里明明写了 "highlight": { "fields": { "title": {} ... UI心虹 交互 2026-03-11 04:54:18 2 回答 71 浏览 搜索输入后滚动条跳到顶部怎么解决? 在做搜索功能时,每次输入新关键词后,列表滚动条会跳回顶部,用户体验特别差。我尝试过用scrollTop保存位置,但重新渲染后还是不行。 代码逻辑是这样的:输入框用v-model绑定查询词,列表用计算属... 一一硕 交互 2026-02-05 15:07:36 2 回答 148 浏览 Vue搜索历史清除按钮点击后列表不更新怎么办? 在做搜索历史功能时遇到个怪问题,点击清除按钮后控制台显示searchHistory数组确实清空了,但页面列表还是显示原有数据。我尝试过手动刷新页面就能消失,但正常应该立即响应才对... 清空历史 {{... Mr.英杰 交互 2026-01-28 23:40:44
最稳妥的方式是把匹配的文字拆分开,用 Vue 的 v-for 来分别渲染匹配和非匹配的部分,这样完全不需要 v-html,避免 XSS 风险:
先写个辅助函数,把文本按关键词拆成数组:
然后在模板里这样用:
这样拆分后渲染,匹配到的文字会带上 highlight 类,没匹配的就是普通文本。
如果你非要用 v-html 也不是不行,但一定要先对原文本做 HTML 转义,再替换关键词:
不过说实话,第一种拆分渲染的方式更干净,不用担心 XSS 问题,也不会有 Vue 的警告。我现在项目里用的都是第一种。