antd design中用到树结构的组件总结。

227 阅读1分钟

在开发中,如果有展示公司层级、学科系统、分类目录的需求的话,就经常会需要将对象数组的结构转成树型结构,然后应用到antd组件里,比如Tree树形控件、TreeSelect树形选择器、树形数据展示的Table等。

Tree image.png

TreeSelect image.png

Table image.png

只需要将数据转换成如下结构即可:

image.png

转换之前就是一普通对象数组

image.png

递归遍历,时间复杂度可能略高,但是我这里数据层级不超过三四层,所以还好。转换的代码如下:(转换成table需要的树形数据)

useEffect(() => {
    const x = testMenu; //要转换的数据
    setLoading(true);
    const resultTemp = arrayToTree(x, -1); 
    const result = deleteChildren(resultTemp);
    //console.log(result)
    setData(result);
    setLoading(false);
    setExpandKeys(tempExpandKey.current);
  }, []);
  
  const count = useRef<number>(1); 
  const tempExpandKey = useRef<React.Key[]>([]); //保存树所有的key
  const getChildren = (data2: MenuManageType[], result: MenuManageType[], pId: number) => {
    if (pId >= -1) {
      for (const item of data2) {
        if (item.parentId === pId) {
          const newItem = {
            id: item.id,
            name: item.name,
            url: item.url,
            path: item.path,
            css: item.css,
            sort: item.sort,
            type: item.type,
            keyValue: count.current,
            children: [],
          };
          result.push(newItem);
          count.current++;
          getChildren(data2, newItem.children, item.id);
        }
      }
    }
  };
  const arrayToTree = (data1: MenuManageType[], pId: number) => {
    const result: MenuManageType[] = [];
    getChildren(data1, result, pId);
    return result;
  };
  //带children渲染table,children为[]也会有+展开符 需要删掉children字段。不知道如何优化
  const deleteChildren = (data3: MenuManageType[]) => {
    const childTemp: MenuManageType[] = data3;
    //console.log(childTemp)
    for (let i = childTemp.length; i >= 0; i--) {
      if (childTemp[i] && childTemp[i].children) {
        if (childTemp[i].children?.length) {
          tempExpandKey.current.push(childTemp[i].id);
          deleteChildren(childTemp[i].children);
        } else {
          delete childTemp[i].children;
        }
      }
    }
    return data3;
  };

写的很烂,大佬如果有修改意见,请尽管提出。

如果想要table的树形结构在第二列展开可以加一行,不过文档中好像没有给出 expandIconColumnIndex={1}

image.png

总结:对象数组扁平化转成树形结构这个算法还挺常用的,还可以继续优化一下,不用递归,时间复杂度太高,还可以提取出来做成一个通用的函数。