树形数据递归过滤

2,870 阅读1分钟

场景

树形数据过滤, 并保留原有树形结构不变, 即如果有子集被选中,父级同样保留。

思路

  1. 对数据进行处理,根据过滤标识对匹配的数据添加标识。如visible:true
  2. 对有标识的子集的父级添加标识visible:true
  3. 根据visible标识对数据进行递归过滤,得到最后的数据

代码

    /*
     *	对表格数据进行处理
     *	data 为树形数据数组
     *	filter 为过滤参数即用户输入的值
     *	filterType 为用户通过什么字段与filter 匹配
     */
    filterMenu(data, filter, filterType) {
      const traverse = data => {
        data.forEach(child => {
          child.visible = this.filterMethod(filter, child, filterType);
          if (child.children) traverse(child.children);
          if (!child.visible && child.children?.length) {
            let visible = !child.children.some(child => child.visible);
            child.visible = visible === false;
          }
        });
      };
      traverse(data);
      return this.filterDataByVisible(data);
    },

    // 根据传入的值进行数据匹配, 并返回匹配结果
    filterMethod(val, data, filterType) {
      return data[filterType].includes(val);
    },

    // 递归过滤符合条件的数据
    filterDataByVisible(data) {
      return data.filter(item => {
        if (item.children) {
          item.children = this.filterDataByVisible(item.children);
        }
        if (item.visible) {
          return true;
        }
      });
    }

举例

//模拟数据
let  mockData=[
    {
    id:1,
    name:'测试1',
    children:[
     {
      id:11,
      name:'测试二级1',
     }
    ]
    },
     {
    id:2,
    name:'测试2',
    children:[
     {
      id:21,
      name:'测试二级2',
     }
    ]
    }
]

// val为输入的值
// 过滤后的数据myTree
let myTree = this.filterMenu(mockData, val, 'name');