实现的效果为:
1、勾选查询,新增、修改、删除不选中。
2、勾选新增、修改、或删除,查询选中。
3、查询取消勾选,则新增、修改、删除都取消勾选
4、新增、修改、删除任何一个取消勾选,查询不取消勾选
5、同一个菜单下,查询接口和当前接口下的操作按钮需要分组
数据结构如下:
[
{
id: 'shchapi',
code: 'shchapi',
bizSysCode: 'shchapi',
name: '主应用',
menuSeqId: 1,
parent: null,
children: [
{
id: 'departmentManagement',
code: 'departmentManagement',
name: '部门管理',
menuSeqId: 1,
parent: 'shchapi',
menuUrl: 'departmentManagement/department',
children: [
{
id: 'department:query',
code: 'department:query',
name: '查询',
parent: 'departmentManagement',
requestMethod: 'POST',
btnUrl: '/base/admin/query',
btnGroup: [
{
commonPrefix: 'department',
isQuery: '1'
}
]
},
{
id: 'department:add',
code: 'department:add',
name: '新增',
parent: 'departmentManagement',
requestMethod: 'POST',
btnUrl: '/base/admin/add',
btnGroup: [
{
commonPrefix: 'department',
isQuery: '0'
}
]
},
{
id: 'department:edit',
code: 'department:edit',
name: '修改',
parent: 'departmentManagement',
requestMethod: 'POST',
btnUrl: '/base/admin/edit',
btnGroup: [
{
commonPrefix: 'department',
isQuery: '0'
}
]
},
{
id: 'department:delete',
code: 'department:delete',
name: '删除',
parent: 'departmentManagement',
requestMethod: 'POST',
btnUrl: '/base/admin/delete',
btnGroup: [
{
commonPrefix: 'department',
isQuery: '0'
}
]
}
]
},
{
id: 'departmentApplication',
code: 'departmentApplication',
name: '部门申请',
parent: 'departmentManagement',
menuSeqId: 1,
menuUrl: 'departmentManagement/departmentApplication',
children: [
{
id: 'departmentApplication:query',
code: 'departmentApplication:query',
name: '待复核(查询)',
parent: 'departmentApplication',
requestMethod: 'POST',
btnUrl: '/base/admin/query',
btnGroup: [
{
commonPrefix: 'departmentApplication:review',
isQuery: '1'
}
]
},
{
id: 'departmentApplication:review:review',
code: 'departmentApplication:review:review',
name: '待复核(复核)',
parent: 'departmentApplication',
requestMethod: 'POST',
btnUrl: '/base/admin/review',
btnGroup: [
{
commonPrefix: 'departmentApplication:review',
isQuery: '0'
}
]
},
{
id: 'departmentApplication:review:revoke',
code: 'departmentApplication:review:revoke',
name: '待复核(撤销)',
parent: 'departmentApplication',
requestMethod: 'POST',
btnUrl: '/base/admin/edit',
btnGroup: [
{
commonPrefix: 'departmentApplication:review',
isQuery: '0'
}
]
},
{
id: 'departmentApplication:review:export',
code: 'departmentApplication:review:export',
name: '待复核(下载)',
parent: 'departmentApplication',
requestMethod: 'POST',
btnUrl: '/base/admin/delete',
btnGroup: [
{
commonPrefix: 'departmentApplication:review',
isQuery: '0'
}
]
},
{
id: 'departmentApplication:reviewed:query',
code: 'departmentApplication:reviewed:query',
name: '已复核(查询)',
parent: 'departmentApplication',
requestMethod: 'POST',
btnUrl: '/base/admin/edit',
btnGroup: [
{
commonPrefix: 'departmentApplication:reviewed',
isQuery: '1'
}
]
},
{
id: 'departmentApplication:reviewed:export',
code: 'departmentApplication:reviewed:export',
name: '已复核(下载)',
parent: 'departmentApplication',
requestMethod: 'POST',
btnUrl: '/base/admin/edit',
btnGroup: [
{
commonPrefix: 'departmentApplication:reviewed',
isQuery: '0'
}
]
}
]
}
]
}
]
具体代码实现如下:
<template>
<el-tree
ref="treeRef"
class="permission-tree"
node-key="id"
show-checkbox
:data="treeData1"
:expand-on-click-node="false"
:check-on-click-node="true"
:props="{
children: 'children',
label: 'name',
value: 'code'
}"
v-bind="$attrs"
@check="handleCheck"
>
</el-tree>
</template>
<script>
/**
* 根据公共前缀进行分组
* btnGroup 数组中 commonPrefix 值一致为一组
* **/
const groupByCommonPrefix = (actions) => {
const groupedActions = {};
actions.forEach((action) => {
const commonPrefix = action.btnGroup[0].commonPrefix;
if (!groupedActions[commonPrefix]) {
groupedActions[commonPrefix] = [];
}
groupedActions[commonPrefix].push(action);
});
return groupedActions;
};
/**
* groupedActions: 通过公共前缀分组后的数据
* commonPrefix: 公共前缀
* isQuery: 1:是查询接口; 0:普通操作按钮
* 返回 isQuery 为 1 的数据
* **/
const findByIsQuery = (groupedActions, commonPrefix, isQuery) => {
if (!(commonPrefix in groupedActions)) {
return [];
}
return groupedActions[commonPrefix].filter(
(action) => action.btnGroup[0].isQuery == isQuery
);
};
export default {
name: 'permissionTree',
props: {
treeData: {
type: Array,
default: () => []
},
props: {
type: Object,
default: () => ({
children: 'children',
label: 'name',
value: 'code'
})
}
},
data() {
return {
treeData1: [
{
id: 'shchapi',
code: 'shchapi',
bizSysCode: 'shchapi',
name: '主应用',
menuSeqId: 1,
parent: null,
children: [
{
id: 'departmentManagement',
code: 'departmentManagement',
name: '部门管理',
menuSeqId: 1,
parent: 'shchapi',
menuUrl: 'departmentManagement/department',
children: [
{
id: 'department:query',
code: 'department:query',
name: '查询',
parent: 'departmentManagement',
requestMethod: 'POST',
btnUrl: '/base/admin/query',
btnGroup: [
{
commonPrefix: 'department',
isQuery: '1'
}
]
},
{
id: 'department:add',
code: 'department:add',
name: '新增',
parent: 'departmentManagement',
requestMethod: 'POST',
btnUrl: '/base/admin/add',
btnGroup: [
{
commonPrefix: 'department',
isQuery: '0'
}
]
},
{
id: 'department:edit',
code: 'department:edit',
name: '修改',
parent: 'departmentManagement',
requestMethod: 'POST',
btnUrl: '/base/admin/edit',
btnGroup: [
{
commonPrefix: 'department',
isQuery: '0'
}
]
},
{
id: 'department:delete',
code: 'department:delete',
name: '删除',
parent: 'departmentManagement',
requestMethod: 'POST',
btnUrl: '/base/admin/delete',
btnGroup: [
{
commonPrefix: 'department',
isQuery: '0'
}
]
}
]
},
{
id: 'departmentApplication',
code: 'departmentApplication',
name: '部门申请',
parent: 'departmentManagement',
menuSeqId: 1,
menuUrl: 'departmentManagement/departmentApplication',
children: [
{
id: 'departmentApplication:query',
code: 'departmentApplication:query',
name: '待复核(查询)',
parent: 'departmentApplication',
requestMethod: 'POST',
btnUrl: '/base/admin/query',
btnGroup: [
{
commonPrefix: 'departmentApplication:review',
isQuery: '1'
}
]
},
{
id: 'departmentApplication:review:review',
code: 'departmentApplication:review:review',
name: '待复核(复核)',
parent: 'departmentApplication',
requestMethod: 'POST',
btnUrl: '/base/admin/review',
btnGroup: [
{
commonPrefix: 'departmentApplication:review',
isQuery: '0'
}
]
},
{
id: 'departmentApplication:review:revoke',
code: 'departmentApplication:review:revoke',
name: '待复核(撤销)',
parent: 'departmentApplication',
requestMethod: 'POST',
btnUrl: '/base/admin/edit',
btnGroup: [
{
commonPrefix: 'departmentApplication:review',
isQuery: '0'
}
]
},
{
id: 'departmentApplication:review:export',
code: 'departmentApplication:review:export',
name: '待复核(下载)',
parent: 'departmentApplication',
requestMethod: 'POST',
btnUrl: '/base/admin/delete',
btnGroup: [
{
commonPrefix: 'departmentApplication:review',
isQuery: '0'
}
]
},
{
id: 'departmentApplication:reviewed:query',
code: 'departmentApplication:reviewed:query',
name: '已复核(查询)',
parent: 'departmentApplication',
requestMethod: 'POST',
btnUrl: '/base/admin/edit',
btnGroup: [
{
commonPrefix: 'departmentApplication:reviewed',
isQuery: '1'
}
]
},
{
id: 'departmentApplication:reviewed:export',
code: 'departmentApplication:reviewed:export',
name: '已复核(下载)',
parent: 'departmentApplication',
requestMethod: 'POST',
btnUrl: '/base/admin/edit',
btnGroup: [
{
commonPrefix: 'departmentApplication:reviewed',
isQuery: '0'
}
]
}
]
}
]
}
]
};
},
methods: {
/**
* 复选框选中事件
* 实现的效果:
* 1、同组内查询节点选中时,其兄弟节点不变
* 2、同组内兄弟节点取消选中时,其相邻兄弟节点取消选中
* 3、同组内其相邻兄弟节点任何一个选中时,查询节点必选中
* 注:
* 同组: commonPrefix 值一致的为同组
* 查询节点 btnGroup: [{commonPrefix:'departmentApplication:review',isQuery:'1'}]
* **/
handleCheck(data, checked) {
if (!data.children) {
// 只处理叶子节点
const parentNode = this.$refs.treeRef.getNode(data).parent;
if (parentNode) {
// 获取当前叶子节点和兄弟节点
const siblings = parentNode.data.children;
const groupByCommonPrefixObj = groupByCommonPrefix(siblings);
const findQueryBySelectedArr = findByIsQuery(
groupByCommonPrefixObj,
data.btnGroup[0].commonPrefix,
'1'
);
if (data.btnGroup[0].isQuery == '1') {
// 如果是查询节点,这取消选中所有非查询兄弟节点
const { commonPrefix } = findQueryBySelectedArr[0].btnGroup[0];
groupByCommonPrefixObj[commonPrefix].forEach((item) => {
if (item.btnGroup[0].isQuery == '0') {
this.$refs.treeRef.setChecked(item, false, false);
}
});
} else if (checked) {
// 如果是费查询节点被选中,这确保查询节点也被选中
this.$refs.treeRef.setChecked(
findQueryBySelectedArr[0],
true,
false
);
}
}
}
},
// 返回选中节点组成的数组
getCheckedNodes(leafOnly, includeHalfChecked) {
return this.$refs.treeRef.getCheckedNodes(leafOnly, includeHalfChecked);
},
// 设置目前勾选的节点
setCheckedNodes(nodes) {
this.$refs.treeRef.setCheckedNodes(nodes);
},
// 返回目前被选中的节点的 key 所组成的数组
getCheckedKeys(leafOnly) {
return this.$refs.treeRef.getCheckedKeys(leafOnly);
},
// 通过 keys 设置目前勾选的节点
setCheckedKeys(keys, leafOnly) {
this.$refs.treeRef.setCheckedKeys(keys, leafOnly);
},
// 设置某个节点的勾选状态
setChecked(data, checked, deep) {
this.$refs.treeRef.setChecked(data, checked, deep);
},
// 重置选中的节点
resetChecked() {
this.$refs.treeRef.setCheckedKeys([]);
}
}
};
</script>