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

更新日期: 2026-04-24 阅读: 11 标签: 组件

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

本文教你用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://fly63.com/article/detial/13694

相关推荐

vue重新渲染组件(重置或者更新)

当数据通过异步操作后,对之前加载的数据进行变更后,发现数据不生效。A组件或者B组件触发数据更新,C组件数据更新了,但是C组件仍显示上一次数据。

Vuetify基于vue2.0,为移动而生的组件框架

Vuetify 支持SSR(服务端渲染),SPA(单页应用程序),PWA(渐进式Web应用程序)和标准HTML页面。 Vuetify是一个渐进式的框架,试图推动前端开发发展到一个新的水平。

React高阶组件中使用React.forwardRef的技巧

之前使用React.forwardRef始终无法应用于React高阶组件中,关键点就是React.forwardRef的API中ref必须指向dom元素而不是React组件。codepen实例请划到底部。

Vue使用Props绑定Object并且传参

通过Props 给子组件传变量,变量是对象时,子组件无法在首次打开时获取到传入对象数据,并且在父组件中改变对象的属性,子组件也是无法监听

Vue中插槽的作用_Vue组件插槽的使用以及调用组件内的方法

通过给组件传递参数, 可以让组件变得更加可扩展, 组件内使用props接收参数,slot的使用就像它的名字一样, 在组件内定义一块空间。在组件外, 我们可以往插槽里填入任何元素。slot-scope的作用就是把组件内的数据带出来

React Hook父组件获取子组件的数据/函数

我们知道在react中,常用props实现子组件数据到父组件的传递,但是父组件调用子组件的功能却不常用。文档上说ref其实不是最佳的选择,但是想着偷懒不学redux,在网上找了很多教程,要不就是hook的讲的太少

使用Vue 自定义文件选择器组件

文件选择元素是web上最难看的 input 类型之一。它们在每个浏览器中实现的方式不同,而且通常非常难看。这里有一个解决办法,就是把它封装成一个组件。

element-ui 的隐藏滚动组件el-scrollbar

为什么要用el-scrollbar,大家都知道,模拟一个滚动不难,而且市面上有很多这样的库。我考虑的,首先项目用的框架是Vue,然后用的组件库是Element,Element官网也有很多滚动

vue中prop属性传值解析

prop的定义:在没有状态管理机制的时候,prop属性是组件之间主要的通信方式,prop属性其实是一个对象,在这个对象里可以定义一些数据,而这些数据可以通过父组件传递给子组件。 prop属性中可以定义属性的类型,也可以定义属性的初始值。

写一个vue组件库_跟着element学习写组件

组件以插件的形式引入使用,当然,也可以直接在页面引入组件文件,两者按需使用。通过源码可知,vue不会重复安装同一个插件。以第一次安装为准,现在,可以在代码中使用组件啦~

点击更多...

内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!