zoukankan      html  css  js  c++  java
  • vue中树状结构转行数据,并渲染成table的方法

    这个算法非常有价值.50块钱提供核心协助

    我qq

    840189859

    我微信

    18500591275

    场景: 我们现在有一个树状结构的数据,如下图:
    在这里插入图片描述
    大概的数据结构如下:

    const tree = {
        value: '根节点',
        children: [
          {
            value: '学校',
            children: [
              {
                value: '学生',
                children: [
                  {
                    value: '年龄',
                    children: [
                      {
                        value: '身高'
                      }
                    ]
                  }
                ]
              }
              ......
            ]
          }
        ]
      } 
     现在我们要将这样的数据转为行数据, 并用vue将其渲染为table, 效果如下:

    在这里插入图片描述

    OK,下面我们一一进行解析。

    第一步,递归树状结构,转化为行数据
    parseTreeToRow(node, data = [], row = []) {
       if (!node.children) {
        data.push(row);
       } else {
         for (let i = 0; i < node.children.length; i++) {
           const child = node.children[i];
           const cell = { value: child.value };
           this.parseTreeToRow(child, data, [...row, cell]);
         }
       }
       return data;
    };
    
    //通过上面的递归函数,解析出来的行数据如下:
    const data = [
        [{ value: '学校'}, { value: '学生' }, { value: '年龄' }, { value: '身高' }],
        [{ value: '成都一中'}, { value: '张三' }, { value: '17' }, { value: '170' }],
        [{ value: '成都二中'}, { value: '李四' }, { value: '17' }, { value: '174' }],
        [{ value: '成都二中'}, { value: '王五' }, { value: '18' }, { value: '168' }],
        [{ value: '成都二中'}, { value: '王五' }, { value: '19' }, { value: '177' }],
        ......
    ];
    第二步,添加rowspan信息

    此时,很明显渲染出来的table并没有进行合并,如果对解析后的行数据二次解析亦可找到其rowspan,这里不做二次解析,我们回到上面的递归函数中,做如下处理:

    
    
    parseTreeToRow(node, data = [], row = []) {
       if (!node.children) {
         data.push(row);
       } else {
         for (let i = 0; i < node.children.length; i++) {
           const child = node.children[i];
           const cell = {
               value: child.value,
               rowspan: this.computeLeafCount(node)
           };
           this.parseTreeToRow(child, data, [...row, cell]);
         }
       }
       return data;
    };
    
    /**
     1. 计算某个节点下叶子节点的数量
     2. @param { Object }    node        节点
     3. @returns { Number }  leafCount   叶子节点的数量
       */
      computeLeafCount(node) {
        if(!node.children){
          node.rowspan = 1;
          return 1;
        } else {
          let leafCount = 0;
          for(let i = 0 ; i < node.children.length ; i++) {
            leafCount = leafCount + this.computeLeafCount(node.children[i]);
          }
          node.rowspan = leafCount;
          return leafCount;
        }
      }
    //解析出的数据如下:
    const data = [
        [{ value: '学校', rowspan: 7 }, { value: '学生', rowspan: 1 }, { value: '年龄', rowspan: 1 }, { value: '身高', rowspan: 1 }],
        [{ value: '成都一中', rowspan: 7 }, { value: '张三', rowspan: 1 }, { value: '17', rowspan: 1 }, { value: '170', rowspan: 1 }],
        [{ value: '成都二中', rowspan: 7 }, { value: '李四', rowspan: 3 }, { value: '17', rowspan: 1 }, { value: '174', rowspan: 1 }],
        [{ value: '成都二中', rowspan: 7 }, { value: '王五', rowspan: 3 }, { value: '18', rowspan: 1 }, { value: '168', rowspan: 1 }],
        [{ value: '成都二中', rowspan: 7 }, { value: '王五', rowspan: 3 }, { value: '19', rowspan: 1 }, { value: '177', rowspan: 1 }],
        ......
    ];
    
    

     但是可以发现,我们需要的合并信息解析到了child中,且相同的单元格只有第一行的rowspan保留,其余要置为0,。

    第三步,处理异常合并信息

    回到递归函数中,

    
    
    parseTreeToRow(node, data = [], row = []) {
       if (!node.children) {
         data.push(row);
       } else {
         for (let i = 0; i < node.children.length; i++) {
           const child = node.children[i];
           const cell = { value: child.value };
            /******************添加的代码******************/
            //深度克隆父亲,因为后代共用了该引用数据
           const extendRow = [ ...JSON.parse(JSON.stringify(row)), cell];
           if (extendRow.length === 1) {    //第一列
             extendRow[0].rowspan = 1;
           } else if (extendRow.length > 1) {
             //将该行的最后一列的rowspan赋给上一列
             //再将自身置为1(避免最后一列无值)
             extendRow[extendRow.length - 2].rowspan = i === 0 ? this.computeLeafCount(node) : 0;
             extendRow[extendRow.length - 1].rowspan = 1;
           }
           /******************添加的代码******************/
           this.parseTreeToRow(child, data, extendRow);
         }
       }
       return data;
    };
    
    //解析后的数据结构如下:
    const data = [
        [{ value: '学校', rowspan: 1 }, { value: '学生', rowspan: 1 }, { value: '年龄', rowspan: 1 }, { value: '身高', rowspan: 1 }],
        [{ value: '成都一中', rowspan: 1 }, { value: '张三', rowspan: 1 }, { value: '17', rowspan: 1 }, { value: '170', rowspan: 1 }],
        [{ value: '成都二中', rowspan: 1 }, { value: '李四', rowspan: 3 }, { value: '17', rowspan: 1 }, { value: '174', rowspan: 1 }],
        [{ value: '成都二中', rowspan: 1 }, { value: '王五', rowspan: 0 }, { value: '18', rowspan: 1 }, { value: '168', rowspan: 1 }],
        [{ value: '成都二中', rowspan: 1 }, { value: '王五', rowspan: 0 }, { value: '19', rowspan: 1 }, { value: '177', rowspan: 1 }],
        ......
    ];
    
    
    <table>
      <tr v-for="(row, i) in data" :key="i">
         <td
           v-for="(cell, j)  in row"
           v-if="cell.rowspan"
           :key="j"
           :rowspan="cell.rowspan"
           :colspan="cell.colspan">
           <div class="cell">{{ cell.value }}</div>
         </td>
       </tr>
     </table>

    大功告成!最后的效果如下:
    在这里插入图片描述

    漫思
  • 相关阅读:
    scheme资料
    lisp 资料
    linux input 文章
    qt 键盘驱动分析
    表达式模板 (C++学习)
    qt 键盘插件(mine)
    qt 私有实现导致plugin 加载 提示 undefined symbol
    Visual C++ 8.0对象布局的奥秘:虚函数、多继承、虚拟继承
    linux内核input子系统解析
    qt 键盘 插件
  • 原文地址:https://www.cnblogs.com/sexintercourse/p/13402206.html
Copyright © 2011-2022 走看看