antd+vue:tree component: The parent node prohibits selection and does not display the selection box - basic accumulation
Recently, when I was writing a backend management system, I encountered a need: permission management. Generally, permission management is divided into different levels according to functional classification.
The renderings are as follows:
Today, the backend raised a requirement, as follows: no matter which layer of parent node it is, the selection box will not be displayed, but will only be displayed as a folded item.
Original words:这一层权限能改成不需要勾选么?就当个分组用
The final rendering is as follows:
Solution:
1. Determine which are the parent nodes and add disabled
attribute to the parent node - this.permissionList is the data source
Determine whether it is a parent node through recursion.
filterMenuList(arr, item) {
arr.forEach((child) => {
if (child.children && child.children.length > 0) {
child.disabled = true;
child = this.filterMenuList(child.children, item);
}
});
return item;
},
Use recursive method:
this.permissionList.forEach((item) => {
if (item.permissions && item.permissions.length > 0) {
item = this.filterMenuList(item.permissions, item);
}
});
Through the above method, you can add the attribute disabled
to the parent node as true.
2. Process the parent node of disabled
through css style
/deep/li.ant-tree-treenode-disabled
> span.ant-tree-checkbox.ant-tree-checkbox-disabled {
display: none !important;
}
/deep/
.ant-tree
li.ant-tree-treenode-disabled
> .ant-tree-node-content-wrapper
> span {
color: rgba(0, 0, 0, 0.65) !important;
}
3. The complete code is as follows:
<template>
<a-modal
title="编辑API权限"
:visible.sync="visible"
:width="800"
:maskClosable="true"
@cancel="handleClose"
@ok="handleSubmit"
>
<div id="topId"></div>
<a-tabs tab-position="left">
<a-tab-pane
forceRender
v-for="(group, index) in permissionList"
:key="index + 1"
:tab="group.displayName"
>
<a-tree
ref="permissionTree"
v-model="group.value"
checkable
checkStrictly
:defaultExpandAll="true"
:treeData="group.permissions"
:replaceFields="replaceFields"
@check="onCheck($event, group)"
>
</a-tree>
</a-tab-pane>
</a-tabs>
</a-modal>
</template>
<script>
import {
putApiPermission } from '@/services/menu';
export default {
name: 'addPermissionList',
components: {
},
data() {
return {
visible: false,
loadLoading: false,
permissionList: [],
id: undefined,
replaceFields: {
value: 'permissionName',
title: 'displayName',
children: 'children',
key: 'permissionName',
},
menuRoteIds: [],
};
},
methods: {
onCheck(obj, item) {
item.value = obj.checked || [];
this.$forceUpdate();
},
handleShow(row, permissionList) {
this.visible = true;
this.id = row.id;
this.permissionList = [...permissionList];
this.menuRoteIds = [...row.permissionNames];
this.permissionList.forEach((item) => {
item.value = [];
if (this.menuRoteIds.includes(item.groupName)) {
item.value.push(item.groupName);
}
if (item.permissions && item.permissions.length > 0) {
item = this.filterMenuList(item.permissions, item);
}
});
this.$nextTick(() => {
document.getElementById('topId').scrollIntoView(true);
});
},
filterMenuList(arr, item) {
arr.forEach((child) => {
if (this.menuRoteIds.includes(child.permissionName)) {
item.value.push(child.permissionName);
}
if (child.children && child.children.length > 0) {
child.disabled = true;
child = this.filterMenuList(child.children, item);
}
});
return item;
},
handleClose() {
this.visible = false;
},
handleSubmit() {
let arr = [];
this.permissionList &&
this.permissionList.forEach((item) => {
arr = arr.concat(item.value);
});
let params = {
permissionNames: arr || [],
};
this.loadLoading = true;
putApiPermission(this.id, params)
.then(() => {
this.$message.success('保存成功');
this.$emit('ok');
this.handleClose();
})
.finally(() => {
this.loadLoading = false;
});
},
},
};
</script>
<style scoped>
/deep/.ant-modal-body {
height: 500px;
overflow-y: auto;
}
/deep/li.ant-tree-treenode-disabled
> span.ant-tree-checkbox.ant-tree-checkbox-disabled {
display: none !important;
}
/deep/
.ant-tree
li.ant-tree-treenode-disabled
> .ant-tree-node-content-wrapper
> span {
color: rgba(0, 0, 0, 0.65) !important;
}
</style>