Vue3 搜索高亮

50 阅读1分钟

搜索高亮,简单极了,正则匹配替换不就好了!

桥豆麻袋~ 如果词语之间相互重叠了,要怎么处理呢! 自定义指令 image.png

eg: 语句「为什么我的眼里常含泪水?因为我对这土地爱得深沉」,高亮词语:「含泪」「泪水」。

搜索可以通过对单个词进行标记,把所有匹配上的词的下标记录在数组内,后续再进行去重即可。

image.png

// 搜索词匹配 TS
const highlightKeywords = (originStr: string, keywordArr?: Array<string>) => {
  if (!keywordArr?.length) return originStr
  let resultStr: string = '' // 最终返回的字符串html
  const getReplaceStr = (str: string) =>
    `<span class="search-match">${str}</span>`
  let matchArr: number[] = [] // 需要标红的字的下标数组
  keywordArr.forEach((keyword: string) => {
    let filterStr = originStr
    let stopFlag = false
    while (!stopFlag && filterStr && keyword) {
      const index = filterStr.indexOf(keyword) // 返回匹配的第一个字符的下标
      if (index === -1) stopFlag = true
      else {
        keyword.split('').forEach((s: string, i: number) => {
          matchArr.push(index + Number(i))
        })
        filterStr =
          filterStr.substring(0, index) + ' ' + filterStr.substring(index + 1)
      }
    }
  })


  matchArr = Array.from(new Set(matchArr)) // 去重
  // 标红
  originStr.split('').forEach((char: string, charIndex: number) => {
    resultStr += matchArr.includes(charIndex) ? getReplaceStr(char) : char
  })
  return resultStr
}

其他

函数要不要调整成自定义指令? Vue的官方文档,很清晰的描述了关于自定义指令的应用场景,是和DOM访问底层的逻辑,而高亮更多的是对字符串的调整。(像类似v-focus这类聚集一类的,是强依赖DOM的,使用自定义指令较为合适~) image.png

image.png