树形控件选择子级勾选父级,以及所有子级, 取消勾选仅取消子级
在项目中,可能会遇到这种场景,比如权限配置的时候,页面权限和菜单权限以tree的形式来配置,而且不用半选,菜单在页面的下面,转载请说明出处!!!!
比如说只想勾选页面,而不想勾按钮权限的话,这样是实现不了的,这样我们只能自己实现了,当然,如果不闲麻烦的话可以直接在el-tree上设置
check-strictly 设置父子不关联 |
如果只设置这个属性的话。勾选的子节点不会被选中,关联的父节点也不会被选中
,但是我在这已经给大家做好了直接上代码,有用的话点个赞
这是html部分代码,由于是vue3写的等下我只展示用到的部分代码
data就是树形图数据
咱就只看check的事件针对做处理就好了
<el-tree:default-expand-all="true"show-checkboxref="pSelectTree":render-after-expand="false":data="allPermissionDataSource.format":props="treeProps"@check="onPTreeCheck"check-strictlynodeKey="id"></el-tree>
这个是点击复选框触发的事件,里面用到了两个参数,一个是当前点击的内容,另外用到了
const onPTreeCheck = (_currentData: any, checkData: any) => {// 使用示例//选之前先看之前有没有选中
//setCheckedKeys 是存放选中的keylet 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
};
下面是调用的方法,封装了几个辅助函数
function updateCheckedKeys(treeData, checkedKeys, nodeId, isChecked) {let newCheckedKeys = new Set(checkedKeys);// 辅助函数,用于向上查找并添加所有父节点的IDfunction 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;
} // 辅助函数,用于查找并添加所有子节点的IDfunction addChildrenIds(nodeArray, parentId) {for (let node of nodeArray) {// c 输出当前节点的 IDif (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) {// 输出当前节点的 IDif (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];
}