vben admin BasicTree菜单分配子项不必全部选中时,父级也传给后端
同一个界面内:
<BasicTree
v-model:value="model[field]"
:treeData="treeData"
:fieldNames="{ title: 'resourceName', key: 'id' }"
checkable
toolbar
search
title="菜单分配"
:draggable="true"
:selectable="false"
/>
</template>
</BasicForm>
获取到后端返回数据展示:
const [registerDrawer, { setDrawerProps, closeDrawer }] = useDrawerInner(async (data) => {
resetFields();
setDrawerProps({ confirmLoading: false });
// 需要在setFieldsValue之前先填充treeData,否则Tree组件可能会报key not exist警告
if (unref(treeData).length === 0) {
let res = await getResourceTreeInfoApi();
treeData.value = res.data as any as TreeItem[];
}
isUpdate.value = !!data?.isUpdate;
if (unref(isUpdate)) {
// 过滤掉data.record.resourceIds的父节点
let res = cloneDeep(data.record.resourceIds);
data.record.resourceIds = filterLeafNodeIds(treeData.value, res);
rowId.value = data.record.id;
setFieldsValue({
...data.record,
});
}
});
// 挂载时过滤掉目录父节点---------
function filterLeafNodeIds(tree, arr2) {
const result = new Set();
// 辅助函数,用于确定节点是否为叶子节点
function isLeafNode(node) {
return node.children.length === 0;
}
// 递归函数,用于遍历树并筛选出叶子节点的id
function traverse(node) {
if (arr2.includes(node.id) && isLeafNode(node)) {
result.add(node.id);
} else if (node.children) {
node.children.forEach((child) => traverse(child));
}
}
// 从树的根节点开始递归
tree.forEach((root) => traverse(root));
// 将 Set 转换为数组并返回
return Array.from(result);
}
前端添加或修改数据时加入父节点
async function handleSubmit() {
try {
const values = await validate();
setDrawerProps({ confirmLoading: true });
// 对data2中的每个id执行操作,如果id是父节点,则直接返回,不再添加---
let ids = cloneDeep(values.resourceIds);
ids.forEach((id) => {
addParentIdsIfNotPresent(id, treeData.value, ids);
});
// data2现在包含了所有id及其所有不在data2中的父节点的id---
if (isUpdate.value) {
values.id = rowId.value;
await updateRoleApi({ ...values, resourceIds: ids });
} else {
await addRoleApi({ ...values, resourceIds: ids });
}
// TODO custom api
closeDrawer();
emit('success');
} finally {
setDrawerProps({ confirmLoading: false });
}
}
// 提交时查找当前节点------
function addParentIdsIfNotPresent(nodeId, data1, data2) {
// 查找当前节点
const node = findNodeById(data1, nodeId);
// 如果当前节点存在且其parentId不是null且不在data2中
if (node && node.parentId !== null && !data2.includes(node.parentId)) {
// 将父节点id添加到data2中
data2.push(node.parentId);
// 递归地添加当前节点的父节点id
addParentIdsIfNotPresent(node.parentId, data1, data2);
}
}
function findNodeById(data, id) {
// 辅助函数,用于根据 id 查找节点
for (const node of data) {
if (node.id === id) return node;
if (node.children) {
const found = findNodeById(node.children, id);
if (found) return found;
}
}
return null;
}
//-------