1、先上效果
树型控件,选中项形成一棵新的树,若父选中,子自动选中,子取消,父不取消,子选中,所有的父节点自动取消。同时支持模糊检索,会检索出所有包含该内容的关联节点。
2、环境准备
1、react18
2、antd 4+
3、代码实现
原理:利用antd的tree组件,可以通过设置Tree组件的**checkable
属性为true
,启用了多选功能,当节点被选中或取消选中时,会触发onCheck
事件,我们可以在该事件处理函数中更新checkedKeys**状态 通过控制checkedKeys来实现你想要的选中,核心代码如下:
checkStrictly设置为true,表示子节点选择受控,
javascript
<DirectoryTree
...
checkable={checkable}
expandedKeys={expandedKeys}
treeData={treeData || []}
checkedKeys: checkKeys,
checkStrictly: true,
onCheck: (selectedKeys: any, other) => {
// 当前节点的所有下级子节点
const childrenNodeKeys = getAllChildrenNodeKey(other?.node);
const node: any = other?.node;
if (other?.checked) {
// 当前节点的所有上级父节点
const parentKeys = Array.isArray(node?.parentId) ? node?.parentId : [];
let currentSelectedKeys = [...selectedKeys?.checked, ...parentKeys, ...childrenNodeKeys].filter(
(item: any, i: number, self: any): item is React.Key =>
!!(item && self?.indexOf?.(item) === i),
);
setCheckKeys?.(currentSelectedKeys);
onCheck?.(currentSelectedKeys)
} else {
const currentSelectedKeys = (selectedKeys?.checked || []).filter(((key: string) => !childrenNodeKeys.includes(key) && key !== node?.rowId))
setCheckKeys(currentSelectedKeys);
onCheck?.(currentSelectedKeys);
}
}
/>
当前节点的所有下级子节点
javascript
const getAllChildrenNodeKey = (node: any) => {
const result: any = [];
const getChildrenKey = (childrenList: any) => {
if (childrenList && childrenList.length > 0) {
childrenList.forEach((item: any) => {
if (item?.rowId) {
result.push(item?.rowId)
}
if (item?.children && item?.children.length > 0) {
getChildrenKey(item?.children || []);
}
});
}
}
getChildrenKey(node?.children || []);
return result;
}
tree属性如下:
|---------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------|------------------------------------------------------|---------------------|
| allowDrop | 是否允许拖拽时放置在该节点 | ({ dropNode, dropPosition }) => boolean | - | |
| autoExpandParent | 是否自动展开父节点 | boolean | false | |
| blockNode | 是否节点占据一行 | boolean | false | |
| checkable | 节点前添加 Checkbox 复选框 | boolean | false | |
| checkedKeys | (受控)选中复选框的树节点(注意:父子节点有关联,如果传入父节点 key,则子节点自动选中;相应当子节点 key 都传入,父节点也自动选中。当设置 checkable
和 checkStrictly
,它是一个有checked
和halfChecked
属性的对象,并且父子节点的选中与否不再关联 | string[] | {checked: string[], halfChecked: string[]} | [] | |
| checkStrictly | checkable 状态下节点选择完全受控(父子节点选中状态不再关联) | boolean | false | |
| defaultCheckedKeys | 默认选中复选框的树节点 | string[] | [] | |
| defaultExpandAll | 默认展开所有树节点 | boolean | false | |
| defaultExpandedKeys | 默认展开指定的树节点 | string[] | [] | |
| defaultExpandParent | 默认展开父节点 | boolean | true | |
| defaultSelectedKeys | 默认选中的树节点 | string[] | [] | |
| disabled | 将树禁用 | boolean | false | |
| draggable | 设置节点可拖拽,可以通过 icon: false
关闭拖拽提示图标 | boolean | ((node: DataNode) => boolean) | { icon?: React.ReactNode | false, nodeDraggable?: (node: DataNode) => boolean } | false | config
: 4.17.0 |
| expandedKeys | (受控)展开指定的树节点 | string[] | [] | |
| fieldNames | 自定义节点 title、key、children 的字段 | object | { title: title
, key: key
, children: children
} | 4.17.0 |
| filterTreeNode | 按需筛选树节点(高亮),返回 true | function(node) | - | |
| height | 设置虚拟滚动容器高度,设置后内部节点不再支持横向滚动 | number | - | |
| icon | 自定义树节点图标。 | ReactNode | (props) => ReactNode | - | |
| loadData | 异步加载数据 | function(node) | - | |
| loadedKeys | (受控)已经加载的节点,需要配合 loadData
使用 | string[] | [] | |
| multiple | 支持点选多个节点(节点本身) | boolean | false | |
| rootStyle | 添加在 Tree 最外层的 style | CSSProperties | - | 4.20.0 |
| selectable | 是否可选中 | boolean | true | |
| selectedKeys | (受控)设置选中的树节点,多选需设置 multiple
为 true | string[] | - | |
| showIcon | 是否展示 TreeNode title 前的图标,没有默认样式,如设置为 true,需要自行定义图标相关样式 | boolean | false | |
| showLine | 是否展示连接线 | boolean | { showLeafIcon: ReactNode | ((props: AntTreeNodeProps) => ReactNode) } | false | |
| switcherIcon | 自定义树节点的展开/折叠图标 | ReactNode | ((props: AntTreeNodeProps) => ReactNode) | - | renderProps: 4.20.0 |
| titleRender | 自定义渲染节点 | (nodeData) => ReactNode | - | 4.5.0 |
| treeData | treeNodes 数据,如果设置则不需要手动构造 TreeNode 节点(key 在整个树范围内唯一) | array<{key, title, children, [disabled, selectable]}> | - | |
| virtual | 设置 false 时关闭虚拟滚动 | boolean | true | 4.1.0 |
| onCheck | 点击复选框触发 | function(checkedKeys, e:{checked: boolean, checkedNodes, node, event, halfCheckedKeys}) | - | |
| onDragEnd | dragend 触发时调用 | function({event, node}) | - | |
| onDragEnter | dragenter 触发时调用 | function({event, node, expandedKeys}) | - | |
| onDragLeave | dragleave 触发时调用 | function({event, node}) | - | |
| onDragOver | dragover 触发时调用 | function({event, node}) | - | |
| onDragStart | 开始拖拽时调用 | function({event, node}) | - | |
| onDrop | drop 触发时调用 | function({event, node, dragNode, dragNodesKeys}) | - | |
| onExpand | 展开/收起节点时触发 | function(expandedKeys, {expanded: boolean, node}) | - | |
| onLoad | 节点加载完毕时触发 | function(loadedKeys, {event, node}) | - | |
| onRightClick | 响应右键点击 | function({event, node}) | - | |
| onSelect | 点击树节点触发 | function(selectedKeys, e:{selected: boolean, selectedNodes, node, event}) | - |
关注我并且留言发源码
或者自动下载
https://download.csdn.net/download/yalywq/88814803?spm=1001.2014.3001.5503