效果如下图在线预览APIsHighlight参数说明类型默认值text文本stringundefinedpatterns需要高亮的文本内容string[][]autoEscape自动转义。默认情况下patterns中的元素会被转化为正则表达式进行匹配这个过程中需要进行自动转义正则表达式最终匹配的是元素的字面内容例如\(匹配的就是\(。如果你需要Highlight组件去匹配使用patterns中元素本身构造的正则表达式例如\(匹配的是(则可以设为false。如果你看不懂这些不要改这个设置。booleantruecaseSensitive区分大小写booleanfalsehighlightTag高亮内容的HTML元素类型string‘mark’highlightClass高亮内容的类名stringundefinedhighlightStyle高亮内容的样式CSSProperties{}创建高亮文本组件Highlight.vuescript setup langtsimport{computed,h}fromvueimporttype{CSSProperties}fromvueexportinterfaceProps{text?:string// 文本patterns?:string[]// 需要高亮的文本内容autoEscape?:boolean// 自动转义。默认情况下patterns 中的元素会被转化为正则表达式进行匹配这个过程中需要进行自动转义正则表达式最终匹配的是元素的字面内容例如 \( 匹配的就是 \(。如果你需要 n-highlight 组件去匹配使用 patterns 中元素本身构造的正则表达式例如 \( 匹配的是 (则可以设为 false。如果你看不懂这些不要改这个设置。caseSensitive?:boolean// 区分大小写highlightTag?:string// 高亮内容的 HTML 元素类型highlightClass?:string// 高亮内容的类名highlightStyle?:CSSProperties// 高亮内容的样式}constpropswithDefaults(definePropsProps(),{text:undefined,patterns:()[],autoEscape:true,caseSensitive:false,highlightTag:mark,highlightClass:undefined,highlightStyle:()({})})consttextOrVnodeChildrencomputed((){if(props.patterns.length0||!props.text){return[props.text]}else{constpatternStrprops.patterns.map((word)(props.autoEscape?escapeRegExp(word):word)).join(|)constregexnewRegExp((${patternStr}),props.caseSensitive?g:gi)constsplitItemssplitAndMarkByRegex(props.text,regex)returnsplitItems.map((item:{text:string;isMatch:boolean}){if(item.isMatch){returnh(props.highlightTag,{class:[highlight-mark,props.highlightClass],style:props.highlightStyle},item.text)}returnitem.text})}})functionescapeRegExp(text:string):string{returntext.replace(/[.*?^${}()|[\]\\]/g,\\$)}functionsplitAndMarkByRegex(str:string,regex:RegExp):Array{text:string;isMatch:boolean}{constresult[]letlastIndex0letmatch// 在一个指定字符串中执行一个搜索匹配返回一个结果数组或 nullwhile((matchregex.exec(str))!null){if(match.indexlastIndex){result.push({text:str.slice(lastIndex,match.index),isMatch:false})}result.push({text:match[0],isMatch:true})lastIndexregex.lastIndex// 针对字符串中所有可能的匹配项测试正则表达式还是仅针对第一个匹配项if(!regex.global){break}}if(lastIndexstr.length){result.push({text:str.slice(lastIndex),isMatch:false})}returnresult}/scripttemplatespanclasshighlight-wraptemplate v-for(textOrVnode, index) in textOrVnodeChildren:keyindextemplate v-iftypeof textOrVnode string{{textOrVnode}}/templatecomponent v-else:istextOrVnode//template/span/template在要使用的页面引入script setup langtsimportHighlightfrom./Highlight.vueimport{ref}fromvueconsttextref(Vue Amazing UI 是一个 Vue3 的组件库主题可调全量使用 TypeScript 和 SFC支持 tree shaking有点意思)constpatternsref([Vue Amazing UI,Vue3,TypeScript,SFC,tree shaking])/scripttemplatedivh1{{$route.name}}{{$route.meta.title}}/h1h2classmt30 mb10基本使用/h2Highlight:texttext:patternspatterns/h2classmt30 mb10样式/h2Highlight textVue Amazing UI 全量使用 TypeScript 编写和你的 TypeScript 项目无缝衔接:patterns[Vue Amazing UI, TypeScript]:highlight-style{padding:0 6px,borderRadius:4px,display:inline-block,color:#fff,background:#1677ff,transition:all 0.3s cubic-bezier(0.4, 0, 0.2, 1)}/h2classmt30 mb10区分大小写/h2Highlight textVue Amazing UI 全量使用 TypeScript 编写和你的 TypeScript 项目无缝衔接:patterns[Vue Amazing UI, typeScript]case-sensitive/h2classmt30 mb10高亮标签/h2Highlight:texttext:patternspatternshighlight-tagspan:highlight-style{ fontWeight: 500, color: #ff6900, textDecoration: underline }//div/template