antd+vue:tree组件:父级节点禁止选择并不展示选择框——基础积累
- 1.判断哪些是父节点,给父节点添加`disabled`属性——this.permissionList是数据源
- 2.通过css样式来处理`disabled`的父节点
- 3.完整代码如下:
最近在写后台管理系统的时候,遇到一个需求:就是权限管理,一般权限管理根据功能分类,是会分不同级别的。
效果图如下:
今天后端提了一个需求,如下:就是无论是哪一层的父级节点,都不展示选择框,仅仅当作一个折叠项目展示。
原话:这一层权限能改成不需要勾选么?就当个分组用
最终的效果图如下:
解决思路:
1.判断哪些是父节点,给父节点添加disabled
属性——this.permissionList是数据源
通过递归的方法来判断是否是父节点。
filterMenuList(arr, item) {
arr.forEach((child) => {
if (child.children && child.children.length > 0) {
child.disabled = true;
child = this.filterMenuList(child.children, item);
}
});
return item;
},
使用递归方法:
this.permissionList.forEach((item) => {
if (item.permissions && item.permissions.length > 0) {
item = this.filterMenuList(item.permissions, item);
}
});
通过上面的方法,可以给父节点添加disabled
为true的属性了。
2.通过css样式来处理disabled
的父节点
/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.完整代码如下:
<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>