antd的tree组件:改成单选&同一层级只能展开一个(点击一个节点时另一个展开节点收起)

之前说的做做公司组织架构树的时候用到了tree组件,现在有两个改动:

  • tree节点可选择,但是antd提供的是多选,没有单选的,所以要把原组件改成单选。
  • 树展开的时候太长了,需要对树的展示高度进行限制。

tree组件有一个很好用的东西是onCheck、onExpend函数传入值里面有节点信息,这个信息很重要。 function(checkedKeys, e:{checked: bool, checkedNodes, node, event, halfCheckedKeys})

image.png

一、tree组件改成单选

这个其实并不难,虽然antd没有提供,但是可以自己进行改造。改造起来也很容易:

1、是把样式改了,因为传统的checkbox,方框都是表示多选,圆框是单选,其实就是加个border-radius样式

image.png

改造成↓

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-lVCgs45h-1682648375816)(https://p1-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/68b8b1038c2043119b7662ad090c5528~tplv-k3u1fbpfcp-watermark.image?)]

代码:

.checkbox {
  margin-left: 20px;
  :global {
    .ant-tree-checkbox-inner {
      border-radius: 50% !important;
    }
  }
}

二是通过逻辑实现单选,一行代码搞定,用点击的节点的key直接替代掉原来的checkedkey数组。

onCheck={(_, e) => {
     setCheckedKeys([e.node.key]);
}}

二、限制树高

有两种办法:

  1. tree的层级是公司-事业处-部门-子部门。同一个部门只能展开一个,也就是有一个展开的时候,点另外一个节点时,原结点收起,现点击的结点展开。
  2. 对容纳tree的容器进行高度限制,tree高度超过容器时,展示滚动条。

第一种
image.png

第二种image.png

第二种办法很简单 加个样式即可style={{ height: 200, overflow: 'auto ' }}

第一种代码如下,有e.node.pos、e.expanded的信息就非常好写:

       const keyLevelMap = useRef(new Map()); //记录每一个展开节点的level
       
     //同时只展开一个部门/事业处/公司
            onExpand={(key, e) => {
              console.log(e);
              //e.node.pos第一层0-0,第二层0-0-0,第三层0-0-0-0……
              //e.expanded展开/收起 我记录旧值的样子好像小丑……
              if (e.expanded) {
                const level: number = e.node.pos.split('-').length - 1;
                keyLevelMap.current.set(e.node.key, level); //位置
                const filterKey: Key[] = [];
                key.map((item) => {
                  if (keyLevelMap.current.get(item) != level) {
                    filterKey.push(item);
                  }
                });
                filterKey.push(e.node.key); //加上自身
                setExpandKeys(filterKey);
              } else {
                setExpandKeys(key);
              }
            }}

最开始我不知道有传入的e记录了节点的展开、层级等,然后我就在死做,记录展开的旧值,和新值做对比,得出展开还是收起,以及展开的节点,然后再写些逻辑。

我们第一层的key是c0、c1,第二层的key是c0-m0,c0-m1,第三层部门的key是number类型的id(类似23、29这样的)…我就按照这个规律死做,最后意识到部门底下还有层级 还有子部门,这样写完全不行emmm…没有规律,因为部门和子部门都是number类型id毫无规律,不好控制,其实有上述那么简单的做法,我自己瞎搞这么复杂。

我一开始还觉得treeNode给的api太少了,给我一个字段加层级多好,想不到官方已经做好了层级的记录- -

image.png

(在犯蠢= =ifelse工程师)
image.png

总结下来还是要仔细的看文档,灵活应用,害= =白白浪费时间写错误的做法,记录下来,以后不走弯路。

https://juejin.cn/user/4306112028351885 更多总结在掘金上

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
可以通过在Tree组件中设置onSelect函数来实现点击节点文字展开收起。 具体实现步骤如下: 1. 在Tree组件中设置onSelect函数,该函数会在节点被选中触发。 ```javascript <Tree onSelect={onSelect} // 其他属性 > // 树节点 </Tree> ``` 2. 在onSelect函数中判断被选中的节点是否有子节点,如果有则展开节点,否则不做任何操作。 ```javascript const onSelect = (selectedKeys, { node }) => { const { children } = node.props; if (children) { setExpandedKeys(expandedKeys => { const index = expandedKeys.indexOf(selectedKeys[0]); if (index > -1) { // 如果节点展开,则收起节点 return [...expandedKeys.slice(0, index), ...expandedKeys.slice(index + 1)]; } else { // 如果节点展开,则展开节点 return [...expandedKeys, selectedKeys[0]]; } }); } } ``` 3. 在Tree组件中设置expandedKeys属性,该属性为展开节点的key的数组。 ```javascript <Tree onSelect={onSelect} expandedKeys={expandedKeys} // 其他属性 > // 树节点 </Tree> ``` 完整代码如下: ```javascript import React, { useState } from 'react'; import { Tree } from 'antd'; const Demo = () => { const [expandedKeys, setExpandedKeys] = useState([]); const onSelect = (selectedKeys, { node }) => { const { children } = node.props; if (children) { setExpandedKeys(expandedKeys => { const index = expandedKeys.indexOf(selectedKeys[0]); if (index > -1) { // 如果节点展开,则收起节点 return [...expandedKeys.slice(0, index), ...expandedKeys.slice(index + 1)]; } else { // 如果节点展开,则展开节点 return [...expandedKeys, selectedKeys[0]]; } }); } } return ( <Tree onSelect={onSelect} expandedKeys={expandedKeys} > // 树节点 </Tree> ); } export default Demo; ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值