一、功能描述
当选择第一级的复选框时下面所有内容全选和取消全选,当选择第二的复选框时第三级的所有内容全选和取消全选。只要有一个第三级的内容没有选,二级和一级则不能勾上。第三级内容全选上了,第二级复选框就钩上。第二级也是同样的道理。看图好理解:
二、模拟数据结构(三级嵌套数组结构)
const chooseGroups = ref([
{
id: 1,
title: "一级功能架构",
ischecked:false,
secondLevel: [
{
id: 2,
title:"二级功能架构",
ischecked:false,
thirdLevel: [
{
id:4,
title:"三级功能1",
ischecked:true,
},
{
id:5,
title:"三级功能2",
ischecked:false,
},
{
id:6,
title:"三级功能3",
ischecked:true,
},
]
},
{
id: 3,
title:"二级功能架构",
ischecked:false,
thirdLevel: [
{
id:7,
title:"三级功能1",
ischecked:true,
},
{
id:8,
title:"三级功能2",
ischecked:false,
},
{
id:9,
title:"三级功能3",
ischecked:true,
},
]
},
],
},
{
id: 10,
title: "一级功能架构",
ischecked:false,
secondLevel: [
{
id: 2,
title:"二级功能架构",
ischecked:true,
thirdLevel: [
{
id:4,
title:"三级功能1",
ischecked:true,
},
{
id:5,
title:"三级功能2",
ischecked:true,
},
{
id:6,
title:"三级功能3",
ischecked:true,
},
]
},
{
id: 3,
title:"二级功能架构",
ischecked:false,
thirdLevel: [
{
id:7,
title:"三级功能1",
ischecked:false,
},
{
id:8,
title:"三级功能2",
ischecked:false,
},
{
id:9,
title:"三级功能3",
ischecked:false,
},
]
},
],
},
]);
三、基本思路
1.全选和取消全选
当勾上一级的时候,遍历下面的数组,把二级和三级数组里面的选中值改为true,取消勾上时,把二级和三级数组里面的选中值改为false。当然,把对应的索引也传过来给处理方法,用于标识是哪一个数组里面的,对应上。
当勾上二级的时候,遍历下面的数组,把三级数组里面的选中值改为true,取消勾上时,把三级数组里面的选中值改为false。当然,把对应的索引也传过来给处理方法,用于标识是哪一个数组里面的,对应上。
2.判断是否为全选状态
当三级全勾上的时候,将二级组里面的选中值改为true,顺便判断一下这时候所有二级是不是都选上了,好根据结果看看要不要更新一级的值。如果二级也全部刚好都选上了,则把一级的选中值改为true。当然,把对应的索引也传过来给处理方法,用于标识是哪一个数组里面的,对应上。
四、完整代码
<template>
<div class="container">
<!-- 权限配置 -->
<Commonhead :title="title"></Commonhead>
<div class="main">
<div class="title">
正在配置角色权限:
<p class="title-value">巡检员</p>
</div>
<div class="choose-con">
<div class="choose-item">
<!-- 一级 -->
<div class="choose-item-1" v-for="(item1, index1) in chooseGroups" :key="item1.id">
<el-checkbox v-model="item1.ischecked" :label="item1.title" size="large" class="one" @change="(val)=>LevelOneSelectAll(val,index1)"/>
<!-- 二级 -->
<div class="choose-item-2" v-for="(item2, index2) in item1.secondLevel" :key="item2.id">
<el-checkbox v-model="item2.ischecked" :label="item2.title" size="large" class="two" @change="(val)=>LevelTwoSelectAll(val,index1,index2)"/>
<!-- 三级 -->
<div class="third">
<div class="choose-item-3" v-for="(item3) in item2.thirdLevel" :key="item3.id">
<el-checkbox v-model="item3.ischecked" :label="item3.title" size="large"
@change="LevelThreeSelectAll(index1,index2)"/>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="submit-btn" @click="submit">提交</div>
</div>
</div>
</template>
<script setup>
import Commonhead from "../src/components/Commonhead.vue";
const title = ref("角色管理 > 权限配置");
const chooseGroups = ref([
{
id: 1,
title: "一级功能架构",
ischecked:false,
secondLevel: [
{
id: 2,
title:"二级功能架构",
ischecked:false,
thirdLevel: [
{
id:4,
title:"三级功能1",
ischecked:true,
},
{
id:5,
title:"三级功能2",
ischecked:false,
},
{
id:6,
title:"三级功能3",
ischecked:true,
},
]
},
{
id: 3,
title:"二级功能架构",
ischecked:false,
thirdLevel: [
{
id:7,
title:"三级功能1",
ischecked:true,
},
{
id:8,
title:"三级功能2",
ischecked:false,
},
{
id:9,
title:"三级功能3",
ischecked:true,
},
]
},
],
},
{
id: 10,
title: "一级功能架构",
ischecked:false,
secondLevel: [
{
id: 2,
title:"二级功能架构",
ischecked:true,
thirdLevel: [
{
id:4,
title:"三级功能1",
ischecked:true,
},
{
id:5,
title:"三级功能2",
ischecked:true,
},
{
id:6,
title:"三级功能3",
ischecked:true,
},
]
},
{
id: 3,
title:"二级功能架构",
ischecked:false,
thirdLevel: [
{
id:7,
title:"三级功能1",
ischecked:false,
},
{
id:8,
title:"三级功能2",
ischecked:false,
},
{
id:9,
title:"三级功能3",
ischecked:false,
},
]
},
],
},
]);
// 一级全选和取消全选
const LevelOneSelectAll = (ischeck,index1) => {
// ischeck是复选框选中之后的新值(true,false)
// 如果当前一级勾选上了
if (ischeck) {
// 先更新一级的勾选状态
chooseGroups.value[index1].ischecked = true;
// 然后遍历二级数组更新所有勾选状态为true
chooseGroups.value[index1].secondLevel.forEach(item2 => {
item2.ischecked = true;
// 然后遍历三级数组更新所有勾选状态为true
item2.thirdLevel.forEach(item3 => {
item3.ischecked = true;
});
});
} else {
// 先更新一级的勾选状态
chooseGroups.value[index1].ischecked = false;
// 然后遍历二级数组更新所有勾选状态为fasle
chooseGroups.value[index1].secondLevel.forEach(item2 => {
item2.ischecked = false;
// 然后遍历三级数组更新所有勾选状态为false
item2.thirdLevel.forEach(item3 => {
item3.ischecked = false;
});
});
}
};
// 二级全选和取消全选
const LevelTwoSelectAll = (ischeck,index1,index2) => {
checkLevelTwoAllSelected(index1);
// 如果当前二级勾选上了
if (ischeck) {
// 先更新二级的勾选状态
chooseGroups.value[index1].secondLevel[index2].ischecked = true;
// 然后遍历二级数组更新所有勾选状态为true
chooseGroups.value[index1].secondLevel[index2].thirdLevel.forEach(item3 => {
// 然后遍历三级数组更新所有勾选状态为true
item3.ischecked = true;
});
} else {
// 先更新二级的勾选状态
chooseGroups.value[index1].secondLevel[index2].ischecked = false;
// 然后遍历二级数组更新所有勾选状态为fasle
chooseGroups.value[index1].secondLevel[index2].thirdLevel.forEach(item3 => {
// 然后遍历三级数组更新所有勾选状态为fasle
item3.ischecked = false;
});
}
};
// 三级全选判断
const LevelThreeSelectAll = (index1,index2)=>{
// 假设三级全选上了
let isAllSelcted = true;
// 遍历看看有没有都选上了
for (let i = 0; i < chooseGroups.value[index1].secondLevel[index2].thirdLevel.length; i++) {
// 如果chooseGroups.value[index1].secondLevel[index2].thirdLevel[i].ischecked这个为false就是有没选上的
if(!chooseGroups.value[index1].secondLevel[index2].thirdLevel[i].ischecked){
// 把全选的值改为false
isAllSelcted = false;
break;
}
}
// 做完遍历之后,再来看看最终的假设值isAllSelcted
// 如果全选上了,就把二级的改为true
if(isAllSelcted){
chooseGroups.value[index1].secondLevel[index2].ischecked = true;
}else{
// 如果有 没有选上的,就把二级的改为false
chooseGroups.value[index1].secondLevel[index2].ischecked = false;
}
// 最后再去检查一下所有二级是不是都选上了,好根据结果看看要不要更新一级的值
checkLevelTwoAllSelected(index1);
}
// 检查所有二级是否选上
const checkLevelTwoAllSelected = (index1) =>{
// 假设二级全选上了
let isAllSelcted = true;
// 遍历看看有没有都选上了
for (let i = 0; i < chooseGroups.value[index1].secondLevel.length; i++) {
if(!chooseGroups.value[index1].secondLevel[i].ischecked){
isAllSelcted = false;
break;
}
}
// 做完遍历之后,再来看看最终的假设值isAllSelcted
// 如果全选上了,就把一级的改为true
if(isAllSelcted){
chooseGroups.value[index1].ischecked = true;
}else{
chooseGroups.value[index1].ischecked = false;
}
}
// 提交按钮
const submit = () => {
console.log(chooseGroups.value);
}
</script>
<style scoped>
.container {
padding: 20px;
}
.main {
width: 800px;
margin: 0 auto;
}
.title-value {
color: #f5b90f;
font-weight: 600;
margin-left: 10px;
}
.title {
display: flex;
align-items: center;
}
.choose-item-1 {
margin-left: 10px;
margin-bottom: 10px;
}
.choose-item-2 {
margin-left: 20px;
margin-top: 10px;
}
.choose-item-3 {
margin-top: 10px;
margin-left: 30px;
}
.one::before {
position: absolute;
content: '';
width: 800px;
height: 40px;
left: -10px;
top: 0;
z-index: -1;
background-color: #c5c3bb;
}
.two::before {
position: absolute;
content: '';
width: 780px;
height: 40px;
left: -10px;
top: 0;
z-index: -1;
background-color: #f6f6f6;
}
.third {
display: flex;
align-items: center;
}
.submit-btn {
width: 100px;
height: 30px;
line-height: 30px;
text-align: center;
background-color: #f5b90f;
color: #fff;
font-size: 13px;
border-radius: 5px;
margin: 40px auto;
}
</style>
代码里面有详细的解释,就不必多说了。仔细看一下,注意一下就好了!欢迎交流!