基于react写一个组织树,满足选择组织机构或一线员工进行回收,在某个层级下可多选,但是不可同时选择不同层级回收。如果调度层级回收,提供是否全部回收的按钮。
时间: 2023-05-23 15:05:08 浏览: 147
A:
可以按照以下步骤来基于React实现这个组织树:
1. 安装依赖:可以使用React官方提供的create-react-app来创建一个React应用,并安装相关依赖。然后可以安装一些UI库来快速搭建组织树,如antd、material-ui等。
2. 准备数据:根据需求,需要准备一些组织机构和员工的数据,可以简单地使用一个JSON对象来模拟数据,数据结构类似于下面这样:
```json
{
"name": "公司",
"isOrg": true,
"children": [
{
"name": "部门1",
"isOrg": true,
"children": [
{
"name": "员工1",
"isOrg": false
},
{
"name": "员工2",
"isOrg": false
}
]
},
{
"name": "部门2",
"isOrg": true,
"children": [
{
"name": "员工3",
"isOrg": false
},
{
"name": "员工4",
"isOrg": false
}
]
}
]
}
```
其中,name表示组织机构或员工的名称,isOrg表示是否是组织机构,children表示子节点。
3. 实现组织树:可以使用antd或material-ui中的Tree组件来实现组织树,然后根据数据动态生成节点。
```javascript
import { Tree } from 'antd';
const { TreeNode } = Tree;
function renderTreeNodes(data) {
return data.map(item => {
if (item.children) {
return (
<TreeNode title={item.name} key={item.name}>
{renderTreeNodes(item.children)}
</TreeNode>
);
}
return <TreeNode title={item.name} key={item.name} />;
});
}
function OrgTree({ data }) {
return (
<Tree
checkable
selectable={false}
>
{renderTreeNodes(data)}
</Tree>
);
}
```
可以看到,这里使用了Ant Design中的Tree组件,并且设置了checkable属性,使得节点可以选择。
4. 处理选择逻辑:为了实现选择组织机构或员工进行回收,需要监听Tree组件的onCheck事件,然后在回调函数中更新选择状态。
```javascript
function OrgTree({ data, onChange }) {
const [checkedKeys, setCheckedKeys] = React.useState([]);
function handleCheck(checkedKeysObj) {
const newCheckedKeys = Object.keys(checkedKeysObj).filter(key => checkedKeysObj[key]);
setCheckedKeys(newCheckedKeys);
onChange(newCheckedKeys);
}
return (
<Tree
checkable
selectable={false}
onCheck={handleCheck}
checkedKeys={checkedKeys}
>
{renderTreeNodes(data)}
</Tree>
);
}
```
这里使用了React的Hooks API来管理选择状态,然后在回调函数中调用onChange函数,通知父组件选择状态的变化。
5. 处理限制条件:要满足选择某个层级下可多选,但是不可同时选择不同层级回收,可以在处理选择逻辑的基础上增加一些限制条件。
```javascript
function OrgTree({ data, onChange }) {
const [checkedKeys, setCheckedKeys] = React.useState([]);
function handleCheck(checkedKeysObj) {
const newCheckedKeys = Object.keys(checkedKeysObj).filter(key => checkedKeysObj[key]);
const lastCheckedNode = newCheckedKeys
.map(key => key.split('-'))
.map(keys => keys[keys.length - 1])
.reduce((acc, curr) => acc === curr ? acc : null);
const selectedKeys = lastCheckedNode !== null ?
newCheckedKeys.filter(key => key.endsWith(`-${lastCheckedNode}`)) :
[];
setCheckedKeys(selectedKeys);
onChange(selectedKeys);
}
return (
<Tree
checkable
selectable={false}
onCheck={handleCheck}
checkedKeys={checkedKeys}
>
{renderTreeNodes(data)}
</Tree>
);
}
```
这里使用了一个lastCheckedNode变量来记录最后一次选择的节点,然后根据这个节点来更新已选择的节点。限制条件可以描述为:“如果已选择某个节点,那么只能选择该节点及其子节点”。
6. 实现全部回收:如果需要提供“全部回收”按钮,可以在组件中增加一个按钮,并在按钮点击事件中调用onChange函数。
```javascript
function OrgTree({ data, onChange }) {
const [checkedKeys, setCheckedKeys] = React.useState([]);
function handleCheck(checkedKeysObj) {
const newCheckedKeys = Object.keys(checkedKeysObj).filter(key => checkedKeysObj[key]);
const lastCheckedNode = newCheckedKeys
.map(key => key.split('-'))
.map(keys => keys[keys.length - 1])
.reduce((acc, curr) => acc === curr ? acc : null);
const selectedKeys = lastCheckedNode !== null ?
newCheckedKeys.filter(key => key.endsWith(`-${lastCheckedNode}`)) :
[];
setCheckedKeys(selectedKeys);
onChange(selectedKeys);
}
function handleSelectAll() {
const allKeys = data.map(node => node.name);
setCheckedKeys(allKeys);
onChange(allKeys);
}
return (
<div>
<Tree
checkable
selectable={false}
onCheck={handleCheck}
checkedKeys={checkedKeys}
>
{renderTreeNodes(data)}
</Tree>
<button onClick={handleSelectAll}>全部回收</button>
</div>
);
}
```
这里增加了一个handleSelectAll函数,然后在这个函数中将所有的节点都设置为已选择状态,并调用onChange函数。注意,这里我将全部回收的按钮放在了组件的外部,方便和组件配合使用。
7. 使用组件:最后,将组件导出即可使用。
```javascript
import React from 'react';
...
export default function App() {
const [selectedKeys, setSelectedKeys] = React.useState([]);
function handleSelect(keys) {
setSelectedKeys(keys);
}
return (
<div>
<OrgTree data={data} onChange={handleSelect} />
<p>已选择:{selectedKeys.join(', ')}</p>
</div>
);
}
```
在上面的代码中,我将OrgTree组件包含在一个父组件中,然后在父组件中处理选择状态的变化,并将已选择的节点展示出来。
完整的代码可以参考以下链接:https://codesandbox.io/s/org-tree-with-react-antd-9gxus
阅读全文