Vue3搜索高亮组件:手把手教你实现多关键词标红功能

摘要:做搜索功能时,把匹配的关键词标红是个很常见的需求。不管是文章搜索、后台管理系统,还是日志查看,都需要这个功能。本文教你用Vue3写一个高亮组件,支持多个关键词同时高亮,能自动去重,还做了安全防护,代码可以直接复制到项目里用。

做搜索功能时,把匹配的关键词标红是个很常见的需求。不管是文章搜索、后台管理系统,还是日志查看,都需要这个功能。

本文教你用Vue3写一个高亮组件,支持多个关键词同时高亮,能自动去重,还做了安全防护,代码可以直接复制到项目里用。


一、这个组件能做什么

这个组件解决了搜索结果页的几个实际问题:

  • 输入搜索词后,文本里匹配到的内容自动变红或高亮

  • 支持同时搜多个词,用空格分开就行

  • 大小写都能匹配上

  • 防止XSS攻击,不会被人恶意注入脚本

  • 高亮的颜色和样式可以自己改

  • 只用Vue3,不装任何第三方库


二、实现思路

整个组件的核心逻辑不复杂,分几步走:

  1. 接收两个主要参数:要搜索的文本内容、用户输入的关键词

  2. 处理关键词:去重、去掉空格、转义特殊字符(防止正则表达式报错)

  3. 用正则表达式找出文本里匹配的部分,包上一层带样式的标签

  4. 再用v-html渲染出来,同时做XSS过滤,防止有人搞破坏

  5. 封装成独立组件,想在哪用就在哪用


三、完整代码

新建一个文件,叫 HighlightText.vue,把下面代码复制进去就行。

<template>
  <span class="highlight-text" v-html="highlightContent"></span>
</template>

<script setup>
import { computed } from 'vue'

const props = defineProps({
  // 原始文本
  content: {
    type: String,
    default: ''
  },
  // 搜索词,多个词用空格隔开
  keyword: {
    type: String,
    default: ''
  },
  // 高亮样式类名,可以自己传
  highlightClass: {
    type: String,
    default: 'highlight-keyword'
  }
})

// 高亮处理
const highlightContent = computed(() => {
  const { content, keyword, highlightClass } = props

  // 没有内容或者没有关键词,直接返回原文(转义过的)
  if (!content || !keyword) return escapeHtml(content)

  // 1. 处理关键词:去重、去掉空值
  const keywordList = [...new Set(keyword.split(' ').filter(k => k.trim()))]
  if (keywordList.length === 0) return escapeHtml(content)

  // 2. 转义正则里的特殊字符,防止报错
  const escapedKeywords = keywordList.map(k => 
    k.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')
  )

  // 3. 构造正则:全局匹配,不区分大小写
  const reg = new RegExp(`(${escapedKeywords.join('|')})`, 'gi')

  // 4. 先转义原文防止XSS,再替换高亮
  const safeContent = escapeHtml(content)
  return safeContent.replace(reg, `<spantoken interpolation">${highlightClass}">$1</span>`)
})

// 转义HTML,防止XSS攻击
function escapeHtml(str) {
  if (!str) return ''
  return str
    .replace(/&/g, '&amp;')
    .replace(/</g, '&lt;')
    .replace(/>/g, '&gt;')
    .replace(/"/g, '&quot;')
    .replace(/'/g, '&#39;')
}
</script>

<style scoped>
.highlight-text {
  word-break: break-all;
}

/* 默认高亮样式:红色加粗带浅红背景 */
:global(.highlight-keyword) {
  color: #ff4d4f;
  font-weight: 500;
  background: #fff2f0;
  padding: 0 2px;
  border-radius: 2px;
}
</style>


四、怎么用这个组件

方法一:局部引入(推荐)

在需要用的页面里直接引入:

<template>
  <div>
    <input v-model="searchKey" placeholder="输入关键词" />
    <HighlightText :content="text" :keyword="searchKey" />
  </div>
</template>

<script setup>
import { ref } from 'vue'
import HighlightText from './components/HighlightText.vue'

const searchKey = ref('')
const text = ref('Vue3 是一款优秀的前端框架,Vue3 组合式 API 让代码更清晰,Vue3 生态非常丰富!')
</script>

方法二:全局注册

在 main.js 里注册:

javascript
import { createApp } from 'vue'
import App from './App.vue'
import HighlightText from './components/HighlightText.vue'

const app = createApp(App)
app.component('HighlightText', HighlightText)
app.mount('#app')

注册完就可以在整个项目里直接用了,不用每个页面都引入。


五、几个实用的配置

1. 自定义高亮样式

组件里默认的高亮样式是红色字加浅红背景。如果想改,可以传一个自定义的类名:

<HighlightText 
  :content="text" 
  :keyword="searchKey" 
  highlight-class="my-highlight" 
/>

然后在全局样式里写:

.my-highlight {
  color: #1890ff;
  background: #e6f7ff;
}

2. 多关键词搜索

输入框里敲多个词,用空格隔开就行。比如输入“Vue3 框架”,这两个词都会被高亮。组件会自动去重,同一个词不会重复处理。

3. 特殊字符处理

如果搜索词里包含 . * + ? ^ $ { } [ ] | \ 这类正则表达式里的特殊字符,组件会自动转义,不会报错。


六、组件的几个亮点

安全:里面的 escapeHtml 函数会把 <、>、&、引号这些特殊字符转义掉,然后才渲染到页面上。别人想往你页面里塞脚本是行不通的。

好用:支持多个关键词,自动去重,大小写都能匹配上。没有关键词或者文本为空的时候,正常显示原文,不会出错。

灵活:样式可以随便改,高亮类名可以自己传。没有第三方依赖,放到任何Vue3项目里都能用。

代码易懂:用了Vue3的组合式API,逻辑都写在computed里,代码量不大,注释也写清楚了,新手也能看懂和修改。


七、适用场景

  • 文章搜索结果的摘要高亮

  • 后台管理系统的表格搜索

  • 日志文件的关键词标记

  • 聊天记录里的关键词搜索

  • 任何需要在前端标红关键词的需求


八、注意事项

有一个地方要特别注意:这个组件用了v-html来渲染高亮后的HTML。虽然我们已经做了escapeHtml转义,防止了XSS攻击,但你在修改代码的时候,不要绕开这个转义步骤直接渲染。永远保证用户输入的内容先转义再展示。

另外,如果文本量特别大(比如几万字的长文章),正则替换可能会有点慢。但实际用下来,几千字的文本基本感觉不到延迟,正常使用没问题。


总结

这个组件虽然代码不多,但该有的功能都有了:多关键词高亮、大小写匹配、自动去重、XSS防护、样式可定制。直接复制到项目里就能用,不需要装任何额外的东西。

新手照着代码跑一遍,看看每个函数是干什么的,很快就能上手。有不明白的地方,把代码复制到本地跑一下,改一改试试看,比什么都管用。

本文内容仅供个人学习、研究或参考使用,不构成任何形式的决策建议、专业指导或法律依据。未经授权,禁止任何单位或个人以商业售卖、虚假宣传、侵权传播等非学习研究目的使用本文内容。如需分享或转载,请保留原文来源信息,不得篡改、删减内容或侵犯相关权益。感谢您的理解与支持!

链接: https://shenqiku.cn/article/FLY_13694