文章目录
- 一、构建树形组件
- 二、js代码实现
最近碰到了一个新需求,使用树形选择器实现角色管理功能,当用户选中一个节点时,其所有子节点都会被自动选中;同样,当用户取消选中一个节点时,其所有子节点也会被取消选中。
在开发管理系统时,树形组件是一个常见且重要的组件。在权限管理、菜单管理等场景中,常常需要使用树形结构来表示层级关系。我们需要实现以下功能:
1、节点选中:选中一个节点时,其所有子节点自动选中。
2、节点取消选中:取消选中一个节点时,其所有子节点也取消选中。
一、构建树形组件
树形组件代码:
<a-tree
ref="treeRef"
checkable
:treeData="treeData"
:checkedKeys="checkedKeys"
:expandedKeys="expandedKeys"
:selectedKeys="selectedKeys"
:checkStrictly="checkStrictly"
:clickRowToExpand="false"
title="所拥有的权限"
@check="onCheck"
@select="onTreeNodeSelect"
>
<template #title="{ slotTitle, ruleFlag }">
{{ slotTitle }}
<Icon v-if="ruleFlag" icon="ant-design:align-left-outlined" style="margin-left: 5px; color: red" />
</template>
</a-tree>
二、js代码实现
/**
* 点击选中
*/
function onCheck(o, { node }) {
const nodeKey = node.key;
const allCheckedKeys = new Set(checkedKeys.value);
const childKeys = getAllChildKeys(nodeKey, treeData.value);
if (o.checked.includes(nodeKey)) {
// 如果是选中,将所有子节点也选中
childKeys.forEach((childKey) => allCheckedKeys.add(childKey));
} else {
// 如果是取消选中,将所有子节点也取消选中
childKeys.forEach((childKey) => allCheckedKeys.delete(childKey));
}
checkedKeys.value = Array.from(allCheckedKeys);
}
function getAllChildKeys(nodeKey, treeData) {
let childKeys = [];
function findChildKeys(nodes) {
nodes.forEach((item) => {
if (item.key === nodeKey) {
addChildKeys(item);
} else if (item.children) {
findChildKeys(item.children);
}
});
}
function addChildKeys(node) {
childKeys.push(node.key);
if (node.children) {
node.children.forEach((child) => addChildKeys(child));
}
}
findChildKeys(treeData);
return childKeys;
}
说明:上面的node 是在 onCheck 函数中解构出来的一个参数。这个参数实际上是由树形组件a-tree 在触发 check 事件时传递的。具体来说,onCheck 函数的签名是 (o, { node }),其中 o 是包含选中状态的对象,{ node } 是包含当前节点信息的对象。
这里的 onCheck 是绑定在 check 事件上的处理函数。
a-tree组件内部触发 check 事件时,传递了以下参数:
this.$emit('check', checkedKeys, { node });
其中,checkedKeys 是当前所有被选中的节点的 key 值,{ node } 是当前操作的节点信息对象。
在父组件中,onCheck 事件处理函数会接收到这些参数:
function onCheck(checkedKeys, { node }) {
console.log('Checked keys:', checkedKeys);
console.log('Node:', node);
}
这样,onCheck 函数的签名 (checkedKeys, { node }) 就可以分别接收到 checkedKeys 和 node 对象。
check还有其他的参数:
最后实现效果: