react实现权限树
权限树实现方法
在React中实现权限树通常需要结合数据结构设计、组件渲染和权限控制逻辑。以下是几种常见的实现方式:
递归组件渲染
使用递归组件渲染树形结构是最直接的方式。定义一个树节点组件,该组件能够递归渲染子节点。
const TreeNode = ({ node, onCheck }) => {
return (
<div>
<label>
<input
type="checkbox"
checked={node.checked}
onChange={() => onCheck(node.id)}
/>
{node.name}
</label>
{node.children && (
<div style={{ marginLeft: '20px' }}>
{node.children.map(child => (
<TreeNode key={child.id} node={child} onCheck={onCheck} />
))}
</div>
)}
</div>
);
};
扁平数据结构转换
将后端返回的扁平权限数据转换为树形结构,便于渲染。
function buildTree(items, parentId = null) {
return items
.filter(item => item.parentId === parentId)
.map(item => ({
...item,
children: buildTree(items, item.id)
}));
}
状态管理
使用React状态或状态管理库(如Redux)来管理权限树的选中状态。
const [treeData, setTreeData] = useState([
{
id: 1,
name: '系统管理',
checked: false,
children: [
{
id: 2,
name: '用户管理',
checked: false,
children: []
}
]
}
]);
const handleCheck = id => {
const updateChecked = nodes =>
nodes.map(node => ({
...node,
checked: node.id === id ? !node.checked : node.checked,
children: node.children ? updateChecked(node.children) : []
}));
setTreeData(updateChecked(treeData));
};
父子联动选择
实现父节点选中时自动选中所有子节点,子节点全部选中时自动选中父节点。
const updateTreeWithSelection = (nodes, id) => {
return nodes.map(node => {
if (node.id === id) {
const newChecked = !node.checked;
const updatedChildren = node.children
? updateChildrenChecked(node.children, newChecked)
: [];
return {
...node,
checked: newChecked,
children: updatedChildren
};
}
if (node.children) {
const updatedChildren = updateTreeWithSelection(node.children, id);
const allChildrenChecked = updatedChildren.every(child => child.checked);
return {
...node,
checked: allChildrenChecked,
children: updatedChildren
};
}
return node;
});
};
const updateChildrenChecked = (children, checked) => {
return children.map(child => ({
...child,
checked,
children: child.children ? updateChildrenChecked(child.children, checked) : []
}));
};
第三方库集成
考虑使用成熟的树形组件库,如antd的Tree组件,可以快速实现复杂功能。
import { Tree } from 'antd';
const { DirectoryTree } = Tree;
const treeData = [
{
title: '系统管理',
key: '0-0',
children: [
{
title: '用户管理',
key: '0-0-0',
isLeaf: true
}
]
}
];
const Demo = () => {
const onSelect = (keys, info) => {
console.log('Trigger Select', keys, info);
};
return (
<DirectoryTree
multiple
defaultExpandAll
onSelect={onSelect}
treeData={treeData}
/>
);
};
权限数据持久化
将选中的权限数据转换为扁平结构,便于提交到后端保存。
function flattenCheckedNodes(nodes) {
let result = [];
nodes.forEach(node => {
if (node.checked) {
result.push(node.id);
}
if (node.children) {
result = result.concat(flattenCheckedNodes(node.children));
}
});
return result;
}
性能优化
对于大型权限树,使用虚拟滚动技术优化性能。
import { FixedSizeList as List } from 'react-window';
const Row = ({ index, style, data }) => (
<div style={style}>
<TreeNode node={data[index]} />
</div>
);
const TreeList = ({ treeData }) => (
<List
height={600}
itemCount={treeData.length}
itemSize={35}
width={300}
itemData={treeData}
>
{Row}
</List>
);
以上方法可以根据实际项目需求进行组合和调整,实现完整的权限树功能。







