关于 antd@4 之后 tree 树形控件不能横向排列这件事
Posted 一百个Chocolate
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了关于 antd@4 之后 tree 树形控件不能横向排列这件事相关的知识,希望对你有一定的参考价值。
遇到这个问题,首先还是搜一下,搜到了相关官方的 issues,如下链接:
树形控件tree需求一个可调节子节点可竖向排列还是横向排列 #8751
在 17 年就有人提及需要支持横向排列,因为这个树形如果按照竖向的话,数据一多了,就显得很长。
当时好像就没有解决这个问题,也看了 antd 之前的版本发现都没有这个配置项,不过倒是找到了相关实现方式,如下链接:
其实就是通过修改样式来做,有了这个思路,我也打算对最新版的 antd 操作一番,不过发现 dom 结构已经变了,不像是之前有 ul li 这种结构了,最底层的 child 节点们外层没有包裹的元素,每一个都是单独的 div。
此时,how to gao?
到底怎么搞?
…
开始寻找
于是,开始了两天的各种尝试,比如说,看到了这篇博客:
React+Ant Design+Tree渲染树形菜单(机构树)
BFS 和 DFS
我也想着应该也可以自定义渲染树,当时还画了一张草图,准备动用一些算法,如下图:
想着对于 ReactNode 来说必须要嵌套才行,所以单纯对于树结构 BFS 不太行,感觉还是得要递归才行,又想到了 DFS,但是这个遍历方式不一样,我又画了一张草图:
感觉这像是 BFS 和 DFS 结合?
所以我还是得判断一下当前节点有没有孩子节点,如果有的话就递归下去,并且当前节点也要显示,于是就有了下面大概的伪代码,核心部分就是这个,也是用的之前 antd@3 的方式,拿出了 TreeNode,不过在 antd@4 之后使用控制台会有提醒不建议使用,推荐使用 treeData。
import Tree from 'antd';
const TreeNode = Tree;
// const data = [...];
// 核心部分
const renderTree = (data: any) =>
if (data && data.length && data[0].children)
return data.map((item: any) =>
return (
<TreeNode title=item.title key=item.key>
item.children && renderTree(item.children)
</TreeNode>
);
);
else
return (
<TreeNode>
data.map((item: any) =>
return (
<TreeNode
title=item.title
key=item.key
className=s.treeNodeChild
></TreeNode>
);
)
</TreeNode>
);
;
const Test = () =>
return (
<Tree>
renderTree(data)
</Tree>
)
export xxx;
我以为这种方式完美解决了,当时思路也很清晰,就是判断没有孩子节点的情况,那时候我可以获得上一个节点的所有孩子节点,把这些孩子节点包在一个 div 里面,然后给这个 div 加一个 flex 就完美解决问题。
可是!
如果给 TreeNode 包裹一个 div 居然就失效了…
孩子节点不会渲染,包括这个 div,试了好几次还是不行,于是这个方案放弃了。
安装两个版本
这个是我突发奇想,我想着既然 antd@3 过去可以通过样式来解决横向排列问题,那么是不是我可以安装两个 antd 版本来解决,当时就搜到了这篇博客,链接如下:
我在 codesandbox 中尝试了一下,会有样式问题,毕竟现在版本和之前版本 dom 结构都不一样了,所以如果之前全局导入了 antd@4 的样式,对于我这个 antd@3 版本的就不太行了。
当时也搜到了这篇博客:
还要改前缀,对当时的我来说还是感觉些许麻烦,还是放弃了这个方式,毕竟共存组件两个版本也不太好,毕竟我不是旧版本升级新版本,我新的又继续往老的兼容感觉有点反调了,想想还是得再找找方式。
自定义渲染节点
后续又翻阅了文档,基本上把每个字段都阅读了一遍,后面发现了 titleRender 这个配置项,于是查阅了一些使用,找了一篇博客样例,如下:
titleRender 自定义渲染节点 (nodeData) => ReactNode
不过这个好像并不能解决我的问题,我是想把没有孩子节点的所有子节点包括在一起,然后加个样式,这个遍历得到的每一个节点,也许是自己使用方式不对,折腾了一会还是没搞出来于是放弃这个方式了。
寻找 npm 包
我想应该会有和我一样需求的人吧,于是我去 npm 去搜索了一些关于 antd tree,我安装了一些,不过好像都没解决这个问题,难道真要我自己手写一个了?
别吧,白嫖多香…
尝试更新 UI
期间我看了一下 material-ui 以及 antd-pro 是否可以,但是 material-ui 风格和国内还是有点区别,而产品的原型又是根据 antd 来的,带有 checkbox,而且一些选中和部分选中情况,material-ui 又没有,所以不考虑了。
这时候,我不知道咋的一下就想到了 vue,而 vue 我当时学习时候就用过 element-ui,好家伙,我立马打开了官网,搜了一下 Tree,好家伙,好家伙,UI 风格居然没多大差别。
我又老规矩 F12 看看元素是怎样的,先在浏览器端改改样式,我发现居然可以!
既然之前还想着 UI 共存两个版本了,那么共存两个 UI 又多大回事呢是吧(逃)
不过为了满足这个特定的需求,不得不妥协加入两个 UI 库,其实也还好,不用担心样式问题,element-ui 样式前缀都会有一个 el。
不过,这时候一想这不是 Vue 的嘛, React 能行嘛,翻了翻,诶,找到了 element-react,在 codesandbox 上写了一个 demo,地址放在这吧:
实现效果如下:
算是解决了这个问题吧。
总结
怎么说呢,最后还是跳出来了,没有一直卡在问题里面,但可能不是一种比较好的解决方式?
至于在大的版本切换之时,将原本的渲染结构重构了一遍这个过程,不太清楚 ul li 结构变成全 div 是为了考虑啥? 性能方面嘛?之前好像在官方文档哪块地方看到过,不过既然改都改了,那么对于这个业务需求暂时就这样解决了。
在此记录一下自己的解决方案,毕竟都换了 UI 库了,不知道各位有没有更好的解决方式,愿意一起探讨。
学如逆水行舟,不进则退。
以上是关于关于 antd@4 之后 tree 树形控件不能横向排列这件事的主要内容,如果未能解决你的问题,请参考以下文章