V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
yazoox
V2EX  ›  React

有没有比较好的方法,把一颗树拍扁了,渲染出来的同时,支持打开关闭父结点?

  •  
  •   yazoox · 2021-07-09 08:40:41 +08:00 · 2497 次点击
    这是一个创建于 994 天前的主题,其中的信息可能已经有所发展或是发生改变。

    如图所示,我现在是用 tree 的 DFS 的方式,创建 react component,画出来的。

    但是,我看很多建议,扁平化数据,用一个 list 来画深层次的结构。拍扁树没问题,逐层缩进问题也不大,但是,“双击”展开或者关闭 parent 结点,始终没有找到好的方法。或者是不是在定义 listnode 的数据结构方面,需要特别的技巧处理一下,能够方便后面的展开 /关闭结点?

    特来请教一下大家。

    谢谢!

    这里有 treenode 方式的 demo

    https://codesandbox.io/s/treeviewdemo-geb72

    image.png

    9 条回复    2021-07-15 14:21:24 +08:00
    rrfeng
        1
    rrfeng  
       2021-07-09 08:45:02 +08:00 via Android
    大把的现成 tree 组件找一个就行了
    hwlhwlxyz
        2
    hwlhwlxyz  
       2021-07-09 09:40:15 +08:00
    我觉得展开关闭就你这样写没有问题,要用的节点数量应该没有多到卡就行了。在不知道最多有几层的情况下,以我的知识,没有其他更好的方法。
    我的需求里面没有觉得展开关闭会有性能方便的影响。但是我遇到的问题是,节点下面增加很多节点(或者说一棵子树)性能不行,会明显感到有点卡顿。大概有几十个节点,有 5 层,但是最多层数是不确定的。我用的是 Angular,新增节点要全部重绘,感觉可能问题在这里,要优化这个太费时间了,我也没什么经验,所以这个问题就先放一边了。
    等待其他研究过的大佬的想法。
    otakustay
        3
    otakustay  
       2021-07-09 09:50:13 +08:00
    我的观点是数据不能拍扁(也没啥用),DOM 结构拍扁
    yazoox
        4
    yazoox  
    OP
       2021-07-09 11:36:05 +08:00
    @otakustay 是的啊。我说的拍扁,意思就是 react 渲染的时候,就直接渲染一个 list 了,而不是渲染一个 node,然后 node 有子结点,再渲染子结点,etc.

    @rrfeng 这个,兄弟,有没有推荐?(最好是能够看到代码的,参考一下设计和实现)
    JerryCha
        5
    JerryCha  
       2021-07-09 12:49:51 +08:00
    扁平化数据结构要带上层次信息的话,用 path 应该是能解决的
    dengshen
        6
    dengshen  
       2021-07-09 13:29:24 +08:00 via iPhone
    拍成链表结构
    otakustay
        7
    otakustay  
       2021-07-09 13:51:07 +08:00
    如果你的数据结构没有拍扁,只是 DOM 扁的话,我理解打开收起不要动画是很容易做的,数据结构上还有 children,直接置个 flag 就行
    要动画的话倒是比较麻烦
    3dwelcome
        8
    3dwelcome  
       2021-07-09 14:10:34 +08:00
    换我就直接 DOM 操作,既然你处理了逐层缩进,那用 JS 来对 list 遍历上下关系节点,还是能靠缩进对比,来找到一定的父子关系。

    有父子关系,就能顺利展开 /关闭子节点。
    qrobot
        9
    qrobot  
       2021-07-15 14:21:24 +08:00
    @yazoox htt 。p 。s://github 。com/HighPerformanceComponent/rc-grid/blob/canary/packages/rc-grid/src/DataGrid.tsx#L309-L348

    你看这段代码, 大概的思路就是这样的,行里面有通过一个方法获取自己的子节点(我这里是通过 onChildrenRows 来获取的),如果你要改成从 list 中获取也是一样的。 循环遍历一下 list 本身,其实就是一个递归就可以处理了。

    你可以下载项目, 执行 yarn 在执行 yarn start 。 然后点击里面的 tree 表格。 你会发现其实就是一个拍扁了的 div list

    > 注意要使用 yarn 不能用 npm
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   5799 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 35ms · UTC 06:14 · PVG 14:14 · LAX 23:14 · JFK 02:14
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.