【记录】vue实现搜索关键词高亮显示

748 阅读1分钟

使用replace进行替换

 // originStr: 原字符串, target:关键词
    highLight (originStr, target) {
      return originStr.replace(target, `<font color=red>${target}</font>`)
    }

通过replace将目标字符串替换成标签文本,如果原字符串中包含有多个目标字符串,可以使用repalceAll进行替换。替换后的字符串结合v-html渲染到页面。

<div v-html="highLight(originStr,target)"></div>

不区分大小写

如果希望不区分大小写,则可以使用正则来实现:

highLight (originStr, target) { 
        const reg = new RegExp(target, 'ig')
        return originStr.replace(reg, (match) => {
          // match是匹配中的字符串
          return `<font color=red>${match}</font>`
        }
    }

实现效果:

高亮.gif

其他的思考

vue.js的官方文档对 v-html 指令的描述有这么一句话:"在网站上动态渲染任意 HTML 是非常危险的,因为容易导致 XSS 攻击。只在可信内容上使用 v-html永不用在用户提交的内容上"。
所以就在想如果不使用v-html指令,该如何实现上述效果?
想到个思路:

高亮显示.jpg
顺带写了个简单的组件验证,也可以实现同样的效果:

<template>
  <div class="wrapper">
    <div v-for="(item,index) in dealSuggestText" :key="index">
      {{item.normal}}<span class="high-linght">{{item.light}}</span>
    </div>
  </div>
</template>

<script>
export default {
  name: 'HighLight',
  props: {
    // 搜索建议
    suggestText: {
      type: String,
      default: ''
    },
    // 关键词
    keyWord: {
      type: String,
      default: ''
    }
  },
  methods: {

  },
  computed: {
    dealSuggestText () {
      // 中转数组,关键字分隔
      const temp = this.suggestText.split(this.keyWord)
      const len = temp.length
      const res = []
      for (let i = 0; i < len - 1; i++) {
        res.push({ normal: temp[i], light: this.keyWord })
      }
      // 最后一项去除关键字
      res.push({ normal: temp[len - 1], light: '' })
      return res
    }
  }
}
</script>

<style lang='less' scoped>
.high-linght {
  color: red;
}

.wrapper{
  display: flex;
}
</style>

如有错误,烦请指正!