树形控件选择子级勾选父级,以及所有子级, 取消勾选仅取消子级
在项目中,可能会遇到这种场景,比如权限配置的时候,页面权限和菜单权限以tree的形式来配置,而且不用半选,菜单在页面的下面,转载请说明出处!!!!
比如说只想勾选页面,而不想勾按钮权限的话,这样是实现不了的,这样我们只能自己实现了,当然,如果不闲麻烦的话可以直接在el-tree上设置
|------------------------|
| check-strictly 设置父子不关联 |
如果只设置这个属性的话。勾选的子节点不会被选中,关联的父节点也不会被选中
,但是我在这已经给大家做好了直接上代码,有用的话点个赞
这是html部分代码,由于是vue3写的等下我只展示用到的部分代码
data就是树形图数据
咱就只看check的事件针对做处理就好了
javascript
<el-tree
:default-expand-all="true"
show-checkbox
ref="pSelectTree"
:render-after-expand="false"
:data="allPermissionDataSource.format"
:props="treeProps"
@check="onPTreeCheck"
check-strictly
nodeKey="id"
></el-tree>
这个是点击复选框触发的事件,里面用到了两个参数,一个是当前点击的内容,另外用到了
javascript
const onPTreeCheck = (_currentData: any, checkData: any) => {
// 使用示例
//选之前先看之前有没有选中
//setCheckedKeys 是存放选中的key
let flag = lastCheckdKey.value.includes(_currentData.id);
// console.log(flag, "iiiii");
lastCheckdKey.value = updateCheckedKeys(
allPermissionDataSource.value.format,
lastCheckdKey.value,
_currentData.id,
flag
);
// console.log(lastCheckdKey.value, "lastCheckdKey.value");
pSelectTree.value.setCheckedKeys(lastCheckdKey.value);
//设置el-tree选中这些key
};
下面是调用的方法,封装了几个辅助函数
javascript
function updateCheckedKeys(treeData, checkedKeys, nodeId, isChecked) {
let newCheckedKeys = new Set(checkedKeys);
// 辅助函数,用于向上查找并添加所有父节点的ID
function findParentIds(treeData, currentId=nodeId, includeSelf = true) {
let parentIds = [];
// 辅助函数,递归地查找父节点
function traverseTree(nodes, targetId) {
// console.log(nodes,targetId,'targetId');
for (let node of nodes) {
if (node.id === targetId) {
// 如果找到了目标节点,并且需要包含自身,则添加它
if (includeSelf) {
parentIds.unshift(targetId); // 在数组开头添加,以保持顺序
}
// 递归地向上查找父节点
if (node.parentId !== null && node.parentId !== undefined) { // 假设parentId为null或undefined表示没有父节点
traverseTree(treeData, node.parentId); // 注意:这里我们遍历整个treeData来查找parentId,但在实际中可能更高效的方法是使用一个map来存储id到节点的映射
}
return; // 找到后退出循环
}
// 如果当前节点有子节点,则递归检查它们
if (node.children) {
traverseTree(node.children, targetId);
}
}
}
// 从根节点开始遍历树
traverseTree(treeData, currentId);
return parentIds;
}
// 辅助函数,用于查找并添加所有子节点的ID
function addChildrenIds(nodeArray, parentId) {
for (let node of nodeArray) {
// c 输出当前节点的 ID
if (node.id === parentId) {
// 如果找到匹配的节点,输出信息
newCheckedKeys.add(parentId);
if (node.children) {
for (let child of node.children) {
newCheckedKeys.add(child.id);
addChildrenIds(node.children, child.id); // 递归地添加子节点的 ID
}
} else {
// 如果节点没有子节点,输出信息
}
return; // 找到匹配的节点后返回,避免不必要的遍历(但这取决于您是否想继续检查其他节点)
}
// 如果当前节点没有匹配的子节点,但包含子节点数组,则递归检查这些子节点
if (node.children) {
addChildrenIds(node.children, parentId);
}
}
// 如果在这一分支中没有找到匹配的节点,输出信息
}
function removeCheckedKeysAndChildren(nodeArray, nodeIdToRemove) {
for (let node of nodeArray) {
// 输出当前节点的 ID
if (node.id === nodeIdToRemove) {
// 如果找到匹配的节点,输出信息
newCheckedKeys.delete(nodeIdToRemove);
if (node.children) {
for (let child of node.children) {
newCheckedKeys.delete(child.id);
removeCheckedKeysAndChildren(node.children, child.id); // 递归地添加子节点的 ID
}
} else {
// 如果节点没有子节点,输出信息
}
return; // 找到匹配的节点后返回,避免不必要的遍历(但这取决于您是否想继续检查其他节点)
}
// 如果当前节点没有匹配的子节点,但包含子节点数组,则递归检查这些子节点
if (node.children) {
removeCheckedKeysAndChildren(node.children, nodeIdToRemove);
}
}
}
if (!isChecked) {
// 如果当前节点不在checkedKeys中,则添加它、它的所有父节点及其所有子节点
findParentIds(treeData,nodeId); // 先添加所有父节点
//父节点关联
let parentArr=findParentIds(treeData)
for (let i = 0; i < parentArr.length; i++) {
newCheckedKeys.add(parentArr[i]);
}
newCheckedKeys.add(nodeId); // 然后添加当前节点本身
addChildrenIds(treeData, nodeId); // 最后添加所有子节点
// console.log(newCheckedKeys, "newCheckedKeys");
} else {
// 如果当前节点在checkedKeys中,则移除它
removeCheckedKeysAndChildren(treeData,nodeId);
// console.log(newCheckedKeys, "newCheckedKeys");
}
return [...newCheckedKeys];
}