Open Chocolate1999 opened 2 years ago
B 站视频已录制,传送门:https://www.bilibili.com/video/BV1AT4y1Q78d
@Chocolate1999 ant升级后Tree组件的节点全部用div标签打平了,而且节点的class没有做任何标识,导致叶子节点无法通过样式横排。其实通过标识有子节点的node节点的class,然后通过样式控制即可。ant的Tree是对rc-tree的二次封装,treeData的数据结构中通过设置isLeaf或者className属性即可达到目的,详情可以查看TreeNode的属性API 或者rc-tree的API https://tree-react-component.vercel.app/
@Chocolate1999 ant升级后Tree组件的节点全部用div标签打平了,而且节点的class没有做任何标识,导致叶子节点无法通过样式横排。其实通过标识有子节点的node节点的class,然后通过样式控制即可。ant的Tree是对rc-tree的二次封装,treeData的数据结构中通过设置isLeaf或者className属性即可达到目的,详情可以查看TreeNode的属性API 或者rc-tree的API https://tree-react-component.vercel.app/
可以
@Chocolate1999 ant升级后Tree组件的节点全部用div标签打平了,而且节点的class没有做任何标识,导致叶子节点无法通过样式横排。其实通过标识有子节点的node节点的class,然后通过样式控制即可。ant的Tree是对rc-tree的二次封装,treeData的数据结构中通过设置isLeaf或者className属性即可达到目的,详情可以查看TreeNode的属性API 或者rc-tree的API https://tree-react-component.vercel.app/
@APIS-X 请问如何通过样式来实现效果。能提供下思路吗?
按照上面的思路可以这么做:
按照上面的思路可以这么做:
- .ant-tree-list-holder-inner 的包裹元素上去掉 flex属性
- 将所有叶子节点的display 改成 inline-flex
是的,我在 stackblitz 写了一个 demo
https://stackblitz.com/edit/vitejs-vite-phmgsx?file=src/App.tsx
原来可以这样子,谢谢各位大佬 @APIS-X @vinoMamba
遇到这个问题,首先还是搜一下,搜到了相关官方的 issues,如下链接:
树形控件tree需求一个可调节子节点可竖向排列还是横向排列 #8751
在 17 年就有人提及需要支持横向排列,因为这个树形如果按照竖向的话,数据一多了,就显得很长。
当时好像就没有解决这个问题,也看了 antd 之前的版本发现都没有这个配置项,不过倒是找到了相关实现方式,如下链接:
修改antd tree组件,使其横向排列
其实就是通过修改样式来做,有了这个思路,我也打算对最新版的 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。
我以为这种方式完美解决了,当时思路也很清晰,就是判断没有孩子节点的情况,那时候我可以获得上一个节点的所有孩子节点,把这些孩子节点包在一个 div 里面,然后给这个 div 加一个 flex 就完美解决问题。
可是!
如果给 TreeNode 包裹一个 div 居然就失效了...
孩子节点不会渲染,包括这个 div,试了好几次还是不行,于是这个方案放弃了。
安装两个版本
这个是我突发奇想,我想着既然 antd@3 过去可以通过样式来解决横向排列问题,那么是不是我可以安装两个 antd 版本来解决,当时就搜到了这篇博客,链接如下:
npm安装同一个包的2个版本
我在 codesandbox 中尝试了一下,会有样式问题,毕竟现在版本和之前版本 dom 结构都不一样了,所以如果之前全局导入了 antd@4 的样式,对于我这个 antd@3 版本的就不太行了。
当时也搜到了这篇博客:
安装两个不同antd 版本、修改antd样式前缀
还要改前缀,对当时的我来说还是感觉些许麻烦,还是放弃了这个方式,毕竟共存组件两个版本也不太好,毕竟我不是旧版本升级新版本,我新的又继续往老的兼容感觉有点反调了,想想还是得再找找方式。
自定义渲染节点
后续又翻阅了文档,基本上把每个字段都阅读了一遍,后面发现了 titleRender 这个配置项,于是查阅了一些使用,找了一篇博客样例,如下:
antd的tree控件怎么渲染特定节点的样式?
不过这个好像并不能解决我的问题,我是想把没有孩子节点的所有子节点包括在一起,然后加个样式,这个遍历得到的每一个节点,也许是自己使用方式不对,折腾了一会还是没搞出来于是放弃这个方式了。
寻找 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,地址放在这吧:
element-ui-tree-demo
实现效果如下:
算是解决了这个问题吧。
总结
怎么说呢,最后还是跳出来了,没有一直卡在问题里面,但可能不是一种比较好的解决方式?
至于在大的版本切换之时,将原本的渲染结构重构了一遍这个过程,不太清楚 ul li 结构变成全 div 是为了考虑啥? 性能方面嘛?之前好像在官方文档哪块地方看到过,不过既然改都改了,那么对于这个业务需求暂时就这样解决了。
在此记录一下自己的解决方案,毕竟都换了 UI 库了,不知道各位有没有更好的解决方式,愿意一起探讨。