需求
项目需求是菜单权限分配,特殊的地方在于,首页为递进关系,可以依次跳转,全国–>省级–>市级,可以选择全国/省级/市级、省级/市级、市级,但是不能跳着选。控制上的难点,在于根据勾选节点,动态控制其他节点的勾选和禁用
思路
常规的解决办法是,遍历结构树,或者通过check事件,遍历节点,这种方法会有些麻烦。这里提供一个比较简便的方法
代码
这里只贴关键代码,仅供参考
<template>
<div class="tree">
<el-tree
show-checkbox
ref="treeRef"
:data="state.treeData"
node-key="id"
:default-expand-all="true"
:default-checked-keys="state.defaultChecked"
highlight-current
:props="defaultProps"
:expand-on-click-node="false"
@check-change="checkChange"
>
</el-tree>
</div>
</template>
<script setup lang="ts">
interface Tree {
id: string;
label: string;
disabled: boolean;
children: Tree[];
}
const defaultProps = {
children: "children",
label: "label",
//关键代码,这里返回一个函数,允许动态控制变量
disabled(data: Tree, node: any) {
if (data.id == "region") {
return state.regionDisabled;
} else if (data.id == "station") {
return state.stationDisabled;
} else {
return false;
}
},
};
const state = reactive({
treeData: [] as Tree[],
defaultChecked: [] as string[],
regionDisabled: false,//省级复选框禁用
stationDisabled: false,//市级复选框禁用
});
//这里根据每次的选中和取消选择,控制其他节点状态
const checkChange = (node: any, isChecked: boolean) => {
//如果节点id非全国、省级、市级,不做处理
if (!["controlCenter", "region", "station"].includes(node.id)) {
return;
}
if (node.id == "controlCenter") {
//id为全国,勾选和取消的判断
if (isChecked) {
treeRef.value.setChecked("region", true, false);
treeRef.value.setChecked("station", true, false);
state.regionDisabled = true;
state.stationDisabled = true;
} else {
state.regionDisabled = false;
state.stationDisabled = false;
}
} else if (node.id == "region") {
//id为省级,勾选和取消的判断
if (isChecked) {
treeRef.value.setChecked("station", true, false);
state.stationDisabled = true;
} else {
state.stationDisabled = false;
}
} else {
//id为市级,如果取消,前两级都取消勾选
if (!isChecked) {
treeRef.value.setChecked("controlCenter", false, false);
treeRef.value.setChecked("region", false, false);
}
}
};
</script>