实现效果如下图,没有相关需求的开发者就不要浪费自己的时间了。网上没看到明显的处理结果,只有一个提供修改flex-direction:column为flex-direction:row的思路,还没有贴代码。然而,那个思路似乎根本行不通,故花时间记录一下。
实现思路如下:
1.tree的节点渲染采用TreeNode的渲染方式代替treeData;
2.将需要横向显示的节点设为行内块级元素;
3.antdesign tree样式修改(1.取消.ant-tree-list-holder-inner的flex布局,2.需要横向展示的节点display:inline-flex;3.需要横向展示的节点宽度修改为20%,整洁好看)
4.操作treeData数据,找出需要横向展示的树节点(注意操作数据的时机,不然可能出现偶尔竖向展示的bug);
伪代码如下:
// 4.找出需要横向展示的树节点
const addIsRow = (arr: any[]) => {
arr.map((item: any) => {
if (item.children && item.children.length > 0) {
addIsRow(item.children);
}
const filterArr = arr.filter((val: any) => {
if (!val.children || val.children.length === 0) {
return val;
}
});
if (filterArr.length === arr.length) item.isRow = true;
});
};
// 2.TreeNode渲染函数
const showTreeNode = (treeData: any[]) => {
return (
treeData && treeData.map((item: any) => {
if (item.children && item.children.length > 0) {
return (
<TreeNode key={item.key} title={item.title} checkable={true}>
{showTreeNode(item.children)}
</TreeNode>
);
} else {
return (
<TreeNode
key={item.key}
title={item.title}
checkable={true}
className={item.isRow ? styles.deepestNode : ''}
/>
);
}
})
);
};
// 1.采用TreeNode渲染代替直接利用treeData属性渲染
<Tree checkable onCheck={wdCheck} checkedKeys={wdCheckedKeys} className={styles.wdTree}>
{showTreeNode(wdTreeData)}
</Tree>
// 3.样式修改
.wdTree {
:global(.ant-tree-list-holder-inner) {
display: block !important;
}
.deepestNode {
display: inline-flex;
width: 20%;
}
}
看到实现思路应该会有很多人吐槽:太low了吧,编程思想太小白了…… 没办法,因为是在antdesign的tree组件上改造的会有很多的局限性。下图是tree组件的部分结构,红框框是每个节点。可以看出树形组件的每个节点在html结构上都是同级的而不是嵌套结构。所以修改.ant-tree-list-holder-inner的flex-direction:row行不通,会导致所有节点全部横向显示,达不到我们想实现的效果。 有同学可能会说:既然你的节点是通过treeNode自己渲染出来的,你可以在需要横向展示的那一类节点外面套一层结构然后采用flex布局啊!好主意,但是行不通!因为你包一层结构就渲染不出来……
最后总结一下,在实现这个需求的时候踩了很多坑。例如,在实现第4步找出需要横向展示节点的时候,开始没有找准规律,children为空就横向展示,这样不仅仅是最深层级的的横向展示,不是最深层级也会横向展示。后来我有给树形数据的每条数据加上level,然后找出最深层级的deepestLevel,当level等于deepestLevel就横向展示依然达不到效果。真正的规律是所有同级别数据的children都为空才能横向展示
大致上效果实现了,但是有个隐患,控制台有警告 Warning: children of Tree is deprecated. Please use treeData instead. 意思就是说TreeNode的渲染方式被废弃了,建议使用treeData属性自动渲染……