Vue树型结构搜索

最近项目中需要使用树状结构,可以无限层级递增,并且还要实现搜索和搜索后选中指定层级。本篇讲总结一下实现思路以及在实现过程中遇到的一些问题和解决办法。
一,步先看看数据结构如下图 ,左侧就是数据解析后展示出来的树状表,三角符号说明有子级可点击展开查看子级内数据。


屏幕快照 2019-03-10 下午4.04.32.png

二,数据解析部分

 handelData(tree,depth,id){
          let that = this;
          let subArr=[];
          for(let i in tree){
            let p=tree[i];
            let obj={
              functionCode: p.functionCode,
              label: p.functionName,
              functionNameAbc:p.functionNameAbc,
              functionSortId: p.functionSortId,
              functionUrl: p.functionUrl,
              parentCode: p.parentCode,
              selected:that.editObj&&that.editObj.functionCode==p.functionCode?true:false,
              key:that.$v4(),
              depth:depth+1,
              showChildren:false,
              pid:id,
              id:id+'0'+that.typeSearch.pid,
              nodes:p.subFuncList.length?that.handelData(p.subFuncList,depth+1,id+'0'+that.typeSearch.pid):[]
            }
            
            that.typeSearch.pid=that.typeSearch.pid+2;
            subArr.push(obj)
          }
          return subArr;
        },

在外部调用递归解析, handelData(tree,depth,id){}函数有三个参数分别是tree(含有子级的节点);depth(当前节点的层级);id(生成父子级对应关系的id,一直是有规律的变化着的)
注意组装subArr数据时
label(当前显示文字内容),
selected(是否选中),
key(唯一标识),
showChildren(是否展示子级,一般设置第0级别为true,其余都为false),
depth(层级关系,注意从0开始为第一级),
id(搜索时匹配使用,id是有规律的,当前id能辨别是否包含父级的id以及父级的父级的id等)
详细结果可以对比一下控制台打印的解析后数据截图:


屏幕快照 2019-03-10 下午4.24.17.png

三,完成了数据组装,接下来就讲一讲vue部分。由于项目内涉及到复用,所以我就单独将树状表单独封装成了组件,这样很大的好处就是后期如果对树状表有什么新的需求改动,也可以更加方便。例如这个页面需要搜索,那个页面只是存展示,这样会更加方便使用参数单独控制即可。

      <div class="search_con" v-if="typeSearch&&typeSearch.clickType=='search'">
        <Input class="searchInput" v-model="searchKey" search clearable @on-change="searchClick(typeSearch.eventClick)" @on-focus="focusClick" :placeholder="typeSearch.placeholder"/>
      </div>
      <div :class="searchKey&&!hasClick?'result_con':'disppear'">
        <template v-for="(item,key) in searchTree">
          <!--:key="random+key" 随机数+key 形式 解决控制台报'Duplicate keys detected: '0.7069392510570331'. This may cause an update error.'-->
          <search-result-tree :item="item" :keyStr="searchKey" :key="random+key" :onClick="resultClick"></search-result-tree>
        </template>
        <template v-if="searchTree.length==0">
         <span class="noneC">无搜索结果</span>
        </template>
      </div>
      <div class="data_con">
        <template v-for="value in dataData">
          <handle-tree
            :treeData="value"
            :onClick="groupClick"
          ></handle-tree>
        </template>
      </div>
      <br/>
    

这里主要涉及两个组件,handle-tree是树状表的展示部分,另外就是search-result-tree 就是展示搜索结果的浮动框。用两个class控制隐藏(disppear)与显示(result_con)。
四,重点说一下搜索高亮。
这部分踩了一个坑。因为是使用了v-html,而且还涉及到了vue的计算属性computed,计算属性是基于它们的依赖进行缓存的。只在相关依赖发生改变时它们才会重新求值。贴部分代码出来:

<template>
  <div class="label_con" v-html="ruleTitle" @click="dataClick"></div>
</template>
 computed: {
        ruleTitle() {//搜索关键字匹配
          let that = this;
          let titleString = that.title;
          // console.log(titleString)
          if (!titleString) {
            return '';
          }
          if (that.searchKey && that.searchKey.length > 0) {
            // 匹配关键字正则
            let replaceReg = new RegExp(that.searchKey, 'g');
            // 高亮替换v-html值
            let replaceString = "<span style='color: #1e67db; font-weight: bold;'>" + that.searchKey + "</span>";
            // 开始替换
            titleString = titleString.replace(replaceReg, replaceString);
          }
          return titleString;
        },
        // 每次传入不一样的key 强制刷新Vue(实时搜索需要)
        key() {
          return this.$route.name !== undefined? this.$route.name +new Date(): this.$route +new Date()
        }
      },

搜索关键字高亮是通过v-html="ruleTitle"这种方式实现,但是实时搜索必须要加一个强制刷新vue的属性,所以就多加了一个key。反观第三步内:key="random+key" 就是触发刷新的部分,random是随机数,采用+key的形式要不然控制台会误以为有相同的key报错。
五,点击搜索结果,树状表展开且选中搜索结果。

handelData(tree,e,s){//递归遍历
          let that = this;
          for(let i in tree){
            //改变选中状态
            tree[i].selected=false;
            if(tree[i].key==e.key){
              tree[i].selected=true;
              if(e.showChildren){
                tree[i].showChildren = true;
              }else {
                tree[i].showChildren = false;
              }

            } else {
              //点击搜索结果才执行
              if(s&&e.id.includes(tree[i].id)){
                tree[i].showChildren = true;
              }
            }
            that.handelData(tree[i].nodes,e,s)
          }
}

handelData(tree,e,s)参数tree为全部树状表数据,e是搜索后点击的那个节点,s是搜索的内容且每次s变化都会触发重新遍历

           if(s&&e.id.includes(tree[i].id)){
                tree[i].showChildren = true;
              }

这段就是利用id的规律性控制哪些该展开哪些不该展开或保持原样。
至此树状表实时搜索就实现了,搜索的结果呢是没有分父子级别的,所有搜索的结果也是通过递归遍历获取,如果有子级的话就把子级剔除放到搜索结果内。最终看下搜索后的截图:


屏幕快照 2019-03-10 下午5.12.28.png
屏幕快照 2019-03-10 下午5.12.58.png
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,616评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,020评论 3 387
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 159,078评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,040评论 1 285
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,154评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,265评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,298评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,072评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,491评论 1 306
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,795评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,970评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,654评论 4 337
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,272评论 3 318
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,985评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,223评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,815评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,852评论 2 351

推荐阅读更多精彩内容

  • Swift1> Swift和OC的区别1.1> Swift没有地址/指针的概念1.2> 泛型1.3> 类型严谨 对...
    cosWriter阅读 11,094评论 1 32
  • 做淘宝真的要刷单么?那些所谓的七天螺旋,如果你一个新开的店,没权重没流量,不刷单哪来的螺旋给你? 淘宝大环境下,小...
    我是盼盼呢阅读 9,722评论 1 16
  • 一七二七,一年一。二七三七,二加一。三七四七,似二七。四七五七,一背一。五七六七,一守一。我六六,你六七,此生有你...
    欲倚阑干不自由阅读 141评论 0 0
  • 行走江湖多年,尘烟几许;莫问路途风华,泛白空话;知己如指,看客如花。回首苍山空白云,低语多不复能记。 我们某一天会...
    墨客物语阅读 309评论 0 0