Vue Highlighter:关键词智能高亮(vue关键词搜索高亮)

1. 简洁轻量

组件代码简洁明了,没有复杂的逻辑和冗余代码,使其非常轻量级。整个组件只有约 80 行代码,但功能完整,这意味着:

  • 加载速度快
  • 运行时消耗资源少
  • 易于理解和维护

2. 类型安全

使用 TypeScript 接口定义了明确的 Props 类型,提供了:

  • 类型检查
  • 清晰的属性文档(包括默认值注释)
  • 减少运行时错误

3. 高度可配置

尽管代码简洁,但提供了丰富的配置选项:

  • 自定义高亮颜色
  • 自定义背景色
  • 控制是否使用粗体
  • 支持区分大小写匹配
  • 支持使用自定义 CSS 类

4. 性能优化

组件使用了 Vue 的计算属性进行优化:

  • highlightStyle 和 highlightedText 都是计算属性,只在依赖变化时重新计算
  • 避免了不必要的重复计算
  • 使用正则表达式一次性替换所有匹配项,而不是多次操作 DOM

5. 安全性考虑

组件包含安全处理:

  • 使用 escapeRegExp 函数转义正则表达式特殊字符,防止用户输入的关键词破坏正则表达式
  • 处理空文本和空关键词的边缘情况
  • 使用 v-html 指令安全地渲染 HTML 内容

6. 灵活的样式选项

提供了两种设置高亮样式的方式:

  • 内联样式:通过 highlightStyle 计算属性动态生成
  • CSS 类:通过 customClass 属性支持外部定义的样式类

7. 易于集成

组件设计使其易于集成到各种场景:

  • 可以用于搜索结果高亮
  • 可以用于文档内容关键词突出显示
  • 可以用于教学内容中重点标记

8. 良好的默认值

组件为所有可选属性提供了合理的默认值:

  • 默认高亮颜色为红色 (#f56c6c)
  • 默认背景色为淡红色 (rgba(245, 108, 108, 0.1))
  • 默认使用粗体
  • 默认不区分大小写

9. 响应式设计

组件充分利用了 Vue 3 的响应式系统:

  • 当 text 或 keyword 属性变化时,高亮效果会自动更新
  • 当样式相关属性变化时,高亮样式会自动更新

10. 代码可读性高

代码结构清晰,变量命名直观,注释完善,使得:

  • 新开发者容易理解
  • 便于后续维护和扩展
  • 可作为学习 Vue 3 组件开发的良好示例

使用示例

新建组件
components/HighlightText/index.vue

<template>
<span class="text" v-html="highlightedText"></span>
</template>
<script lang="ts" setup>
import { computed } from 'vue'
interface Props {
/**
* 要高亮的文本内容
*/
text: string
/**
* 要高亮的关键词
*/
keyword: string
/**
* 高亮的颜色
* @default "#f56c6c"
*/
highlightColor?: string
/**
* 高亮的背景色
* @default "rgba(245, 108, 108, 0.1)"
*/
highlightBgColor?: string
/**
* 是否使用粗体
* @default true
*/
bold?: boolean
/**
* 是否区分大小写
* @default false
*/
caseSensitive?: boolean
/**
* 自定义高亮的CSS类名
*/
customClass?: string
}
const props = withDefaults(defineProps<Props>(), {
highlightColor: '#f56c6c',
highlightBgColor: 'rgba(245, 108, 108, 0.1)',
bold: true,
caseSensitive: false,
customClass: ''
})
// 生成高亮样式
const highlightStyle = computed(() => {
const styles = [
`color: ${props.highlightColor}`,
`background-color: ${props.highlightBgColor}`,
'padding: 0 2px',
'border-radius: 2px'
]
if (props.bold) {
styles.push('font-weight: bold')
}
return styles.join(';')
})
// 生成高亮的HTML
const highlightedText = computed(() => {
if (!props.text || !props.keyword) {
return props.text || ''
}
// 简单文本替换
const flags = props.caseSensitive ? 'g' : 'gi'
const regex = new RegExp(`(${escapeRegExp(props.keyword)})`, flags)
if (props.customClass) {
return props.text.replace(regex, `<span class="${props.customClass}">$1</span>`)
} else {
return props.text.replace(regex, `<span style="${highlightStyle.value}">$1</span>`)
}
})
// 转义正则表达式特殊字符
function escapeRegExp(string: string): string {
return string.replace(/[.*+?^${}()|[\]\\]/g, '\\')
}
</script>
<style lang="less" scoped>
.text {
font-size: 14px;
color: #464646;
}
</style>

新建TS components/index.ts

// 引入项目中的全局组件
import HighlightText from './HighlightText/index.vue'
// 全局对象
const allGlobalComponent = { HighlightText }
// 对外暴露插件对象
export default {
install(app) {
// 注册项目全部的全局组件
Object.keys(allGlobalComponent).forEach((key) => {
// 注册为全局组件
app.component(key, allGlobalComponent[key])
})
}
}

main.ts

// 导入插件对象
import globalComponents from './components/index'
//注册
app.use(globalComponents)

全局使用

<!-- 基本用法 -->
<HighlightText text="这是一段示例文本" keyword="示例" />
<!-- 自定义样式 -->
<HighlightText
text="这是一个重要提示"
keyword="重要"
highlight-color="#1677ff"
highlight-bg-color="rgba(22, 119, 255, 0.1)"
/>
<!-- 使用自定义类 去掉父组件的scoped -->
<HighlightText
text="使用自定义CSS类"
keyword="CSS"
custom-class="my-highlight"
/>
原文链接:,转发请注明来源!