• vue实现搜索关键词高亮


    废话少说先上效果(左侧代码,右侧效果)

    第一组

    在这里插入图片描述

    第二组

    在这里插入图片描述

    第三组

    在这里插入图片描述

    看到什么规律了吗?
    没错!!这份代码就是依靠正则表达式来做出高亮效果,你负责传入str与reg,而函数则负责实现代码的高亮

    解析

    结构部分如下

    <template>
      <div>
        <span
          :class="index%2!==0?'hightLight':''"
          v-for="(item,index) in textData"
          :key="index"
        >{{item}}</span>
      </div>
    </template>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    基本原理就是将传入的str按照正则的规则进行切割,偶数部分负责高亮,奇数部分负责正常显示
    如:
    str与reg分别为

    let str = "高亮几个词语出来好不好";
    let reg = /(高亮|词语)/g;
    
    • 1
    • 2

    将该部分切割为如下数组
    “高亮几个词语出来好不好” —》 [‘’, ‘高亮’, ‘几个’, ‘词语’, ‘出来好不好’] ----》
    知道了基本原理,我们再来看一下代码

    let str = “高亮几个词语出来好不好”;
    let reg = /(高亮|词语)/g;
    let result = {};
    let currentIndex = 0, returnData = [];
    while ((result = reg.exec(str))) {
    returnData.push(str.slice(currentIndex, result.index));
    returnData.push(result[1]);
    currentIndex = result.index + result[0].length;
    }
    if (str.length > currentIndex) {
    returnData.push(str.slice(currentIndex, str.length));
    }
    console.log(returnData);
    this.textData = returnData;

    代码关键在于理解reg.exec,了解这个api的可以直接跳到提取关键字并分组
    正则api——exec
    理解了这个例子,也就基本理解了其他的例子
    我们这样规定,将被两个#和一个空格包围的内容进行高亮即## 内容 ##时,内容要被提取出来并高亮,首先要对其进行分组
    "1212## 4455 #### 0011 ##44488## 000000 ##"就会被分为
    [‘1212’, ‘4455’, ‘’, ‘0011’, ‘44488’, ‘000000’]
    高亮文本与普通文本间隔排序
    在这里插入图片描述

    先来看看下面这部分代码

    let str = "1212## 4455 #### 0011 ##44488## 000000 ##";
    let reg = /##\s+(.*?)\s+##/g;
    console.log(reg.exec(str));
    console.log(reg.exec(str));
    console.log(reg.exec(str));
    console.log(reg.exec(str));
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    执行结果如下

    reg.exec执行

    • 第一次的时候会从字段中找到第一个匹配的字段(## 4455 ##),

    • 第二次:会在第一次匹配的位置后找到第二个匹配的字段(## 0011 ##),

    • 第三次:会在第二次匹配的位置后找到第三个匹配字段(## 000000 ##)

    • 第四次时,剩余的字符已经没有了匹配所有返回null
      也就是说,在null之后的执行结果,都是循环之前的执行结果,所以咱们在执行结果为null时即可停止

    接下来看看执行具体的执行结果

    0: "## 4455 ##"
    1: "4455"
    groups: undefined
    index: 4
    input: "1212## 4455 #### 0011 ##44488## 000000 ##"
    length: 2
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    返回的是一个数组,并带有几个字段属性
    结合一下其正则’0’是拿匹配到正则规则的值,'1’则是匹配到在正则里第一个被括号包起来的值
    ,这个lenth你可以粗糙的理解为需要提取的(即有几个括号)数量+1(这个指的是能匹配到的整体)
    至于为什么是一样的还要用括号括起来,这个后面会说
    知道原理之后我们来看看如何提取关键字并分组

    提取关键字并分组

    提取关键字并分组
    首先我们清楚的看到,通过正则,他会给出三个有用的信息
    第一个是匹配到的正则规则中的值
    第二个是可以拿到我们想要提取出来 即用括号括起来的值
    第三个是该值所在的index
    我们一步一步来
    在这里插入图片描述

    分成这种结构,
    也就是每次exec执行不为null时都做一次区分, 将匹配到的值前方位置提取作为普通字符串,再把当前的关键字提取作为高亮字符串,如下:
    比如第一次匹配时,拿到的值是这样的

    第二次匹配

    /*
    0: "## 4455 ##"
    1: "4455"
    groups: undefined
    index: 4
    input: "1212## 4455 #### 0011 ##44488## 000000 ##"
    length: 2
    */
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    这里index为4,将下标为0-4的字符提取为普通数组,而匹配到的字符串4455作为高亮字符
    此时数组为[‘1212’,‘4455’]

    第二次匹配

    0: "## 0011 ##"
    1: "0011"
    groups: undefined
    index: 14
    input: "1212## 4455 #### 0011 ##44488## 000000 ##"
    length: 2
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    普通字符串应下标为为14-14即空字符串,高亮字符为匹配到的0011
    此时数组为[‘’,‘0011’]
    这里需要明确两个14分别是怎么来的
    第一个14是上一次匹配返回值的 index+上次匹配到字符串字符串## 4455 ##的长度
    在这里插入图片描述

    第二个14是本次配到的index,
    可能这时还有点懵,看这最后一次匹配,你应该就理解了

    第三次匹配

    0: "## 000000 ##"
    1: "000000"
    groups: undefined
    index: 29
    input: "1212## 4455 #### 0011 ##44488## 000000 ##"
    length: 2
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    普通字符串应是下标为24-29即44488,高亮字符为000000
    此时数组为[‘44488’,‘000000’]
    同样需要明确24,29分别是怎么来的
    第一个是上一次匹配返回值的 index+上次匹配到字符串### 0011 ##的长度
    在这里插入图片描述

    第二个则是本次匹配到的index 29
    至此 我们用一个while循环将其包裹,利用上面的规则把对应的值push到数组中,并用一个值缓存上一次的index就可以得到我们的目标数组

    let str = "1212## 4455 #### 0011 ##44488## 000000 ##";
          let reg = /##\s+(.*?)\s+##/g;
          let result = {};
          let currentIndex = 0,
            returnData = [];
          while ((result = reg.exec(str))) {
            console.log(result);
            
            returnData.push(str.slice(currentIndex, result.index));
            returnData.push(result[1]);
            currentIndex = result.index + result[0].length;
          }
    	  // 最后一次匹配的高亮词后可能还有没push到数组中的值
          if (str.length > currentIndex) {
            returnData.push(str.slice(currentIndex, str.length));
          }
          console.log(returnData);  // ['1212', '4455', '', '0011', '44488', '000000']
          this.textData = returnData;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    完整vue代码

    <template>
      <div>
        <span
          :class="index%2!==0?'hightLight':''"
          v-for="(item,index) in textData"
          :key="index"
        >{{item}}</span>
      </div>
    </template>
    
    <script>
    export default {
      data() {
        return {};
      },
      created() {
        this.init();
      },
      methods: {
        init() {
          // let str = "实现搜索词高亮 - 百度文库";
          // let reg = /([高亮词文])/g;
          // let str = "高亮几个词语出来好不好";
          // let reg = /(高亮|词语)/g;
          let str = "1212## 4455 #### 0011 ##44488## 000000 ##";
          let reg = /##\s+(.*?)\s+##/g;
          let result = {};
          let currentIndex = 0,
            returnData = [];
          while ((result = reg.exec(str))) {
            console.log(result);
            
            returnData.push(str.slice(currentIndex, result.index));
            returnData.push(result[1]);
            currentIndex = result.index + result[0].length;
          }
          if (str.length > currentIndex) {
            returnData.push(str.slice(currentIndex, str.length));
          }
          console.log(returnData);
          this.textData = returnData;
        }
      }
    };
    </script>
    
    <style>
    .hightLight {
      color: red;
    }
    </style>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51

    源码附件已经打包好上传到百度云了,大家自行下载即可~

    链接: https://pan.baidu.com/s/14G-bpVthImHD4eosZUNSFA?pwd=yu27
    提取码: yu27
    百度云链接不稳定,随时可能会失效,大家抓紧保存哈。

    如果百度云链接失效了的话,请留言告诉我,我看到后会及时更新~

    开源地址
    码云地址:
    http://github.crmeb.net/u/defu

    Github 地址:
    http://github.crmeb.net/u/defu

    链接:https://juejin.cn/post/7114311817223995428

  • 相关阅读:
    JS_——九九乘法表
    27寸2K显示器 - HKC G27H2
    单行函数,聚合函数课后练习
    XSS详解
    linux上部署python环境
    Oracle 的开窗函数使用详解(二)
    SQLAlchemy学习-12.查询之 order_by 按desc 降序排序
    css如何快速将网站设置为灰色背景
    2022“杭电杯”中国大学生算法设计超级联赛(1)(6题newbie,后续会更新)
    ModelBox姿态匹配:抖抖手动动脚勤做深呼吸
  • 原文地址:https://blog.csdn.net/qq_39221436/article/details/125518799