VUE 前端实现过滤词汇并高亮

632 阅读1分钟

想要在前端实现查询,并且查询出的词高亮显示

  • 前提:数据为两层的对象数组
  • 要求:
    • 查询二级数组的内容进行匹配,若匹配则显示,若不匹配则不显示;
    • 若某个一级内容中的二级内容都不匹配,则一级内容也不显示;
    • 只要二级内容有匹配,则一级菜单显示;

话不多说,上代码喽

html

<template>
  <div id="app">
    <input type="text" @blur="checkWords"/>
      <div v-if="resultData">
      <dl v-for="(item,index) in resultData" style="display: inline-block;margin-right: 30px;">
          <dt v-html="item.menuName" style="font-size: 20px;color: #999;font-weight: bold;"></dt>
          <dd v-if="item.children" v-for="(sItem, sIndex) in item.children" v-html="sItem.menuName"></dd>
      </dl>
  </div>
  </div>
</template>

script

<script>
import {list} from '../static/index' //list为对象数组

export default {
    data(){
        return{
            resultData: JSON.parse(JSON.stringify(list)) //深度克隆,修改之后互相不会影响
        }
},
methods:{
  checkWords(e){
      let key = e.target.value.replace(/\s+/g,""), //去掉空格
        regExp = new RegExp(key,"g");
      this.resultData = JSON.parse(JSON.stringify(list)) //赋值为全部内容,二次过滤时使用

      if(this.resultData){
        this.resultData = this.resultData.filter(item => {
          let isShow = false;//一级菜单是否显示,即二级菜单有匹配的结果返回
          if(item && item.children){
            //过滤二级菜单
            item.children = item.children.filter(sItem => {
              return sItem.menuName.indexOf(key) > -1;
            })

            //高亮
            if(item.children.length > 0) {
              item.children.forEach( item => {
                item.menuName = item.menuName.replace(regExp, function($0){
                  return "<span style='color:red;'>"+$0+"</span>";
                })
              })

              isShow = true;
            }
          }

          return isShow;
        })
      }
    },
}
</script>

static/index.js

export var list=[  {    menuName:'一级菜单01',    children:[      {menuName:"二级菜单0101"},      {menuName:"二级菜单0102"},      {menuName:"二级菜单0103"},    ]
  },
  {
    menuName:'一级菜单02',
    code:'002',
    children:[
      {menuName:'二级菜单0201'},
      {menuName:'二级菜单0202'},
      {menuName:'二级菜单0203'},
      {menuName:'二级菜单0204'},
      {menuName:'二级菜单0205'},
      {menuName:'二级菜单0206'},
    ]
  },
  {
    menuName:'一级菜单03',
    code:'002',
    children:[
      {menuName:'二级菜单0301'},
      {menuName:'二级菜单0302'},
      {menuName:'二级菜单0303'},
      {menuName:'二级菜单0304'},
      {menuName:'二级菜单0305'},
    ]
  }
]