一、需求分析: 1.部门按照树形结构展示一级、二级目录; 2.当一级目录选中时,二级目录自动全选; 3.当二级目录全选时,一级目录自动选中,反之,有一个二级没选中,一级就不被选中; 4.添加全选功能。 二、上代码 备注:此处引用了vant组件的复选框功能。
<template>
<div id="tree">
<div @click="checkAllFun">
<van-checkbox-group v-model="radio" class="checkAll" >
<van-checkbox name="1" checked-color="#ee0a24"><div style="color:#E03716">全选</div></van-checkbox>
</van-checkbox-group>
</div>
<div class="checkThem">
<div v-for="item in firstAllList" :key="item.id">
<!-- 一级的 -->
<div class="check_checkThem_first flex-h flex-vh-center">
<img src="open.png" class="img" v-show="firstFlag==item.id" @click.stop="firstChack('up',item)">
<img src="down.png" class="img" v-show="firstFlag!=item.id" @click.stop="firstChack('down',item)">
<van-checkbox-group v-model="firstList">
<van-checkbox :name="item.id" checked-color="#ee0a24" @click="firstClick(item.id)">{{item.name}}</van-checkbox>
</van-checkbox-group>
</div>
<!-- 二级的 -->
<div class="check_checkThem_second flex-h flex-vh-center" v-show="secondFlag==item.id"
v-for="them in item.children" :key="them.id">
<van-checkbox-group v-model="secondList">
<van-checkbox :name="them.id" checked-color="#ee0a24" @click="secondClick">{{them.name}}</van-checkbox>
</van-checkbox-group>
</div>
</div>
</div>
</div>
</template>
<script>
import Vue from 'vue';
import { Checkbox, CheckboxGroup } from 'vant';
import {get} from "@/request/axios.js";
Vue.use(Checkbox);
Vue.use(CheckboxGroup);
export default {
data() {
return {
radio: [],//全选的
firstList:[],//一级选中的
firstListCopY:[],//记录一级选中的条数
secondList:[],//二级选中的
firstFlag:'',//一级
secondFlag:'',//二级
firstAllList:[{
name:'哈哈',
id:'1',
children:[{
name:'孩子',
id:'2'
}],
flagList:[],//存放被选中的children里的id
}],//一级查询总数据
};
},
mounted() {
this.getFirstList();
},
methods: {
//全选
checkAllFun(){
//全选操作前要清空原有已选列表,否则会出现重复数据,影响后边一级全选后联动全选按钮的判断
this.firstList=[];
this.secondList=[];
//此时还未全选-点击之后进行全选操作
if(this.radio.length===0){
this.firstAllList.forEach(item=>{
this.firstList.push(item.id);
//此处用于记录当一级按钮被触发时,是新添加的还是取消的
this.firstListCopY = JSON.parse(JSON.stringify(this.firstList));
item.children.forEach(them=>{
if(them){
this.secondList.push(them.id);
}
})
})
}else{
//此时已全选-点击之后进行取消全选操作
this.firstList=[];
this.secondList=[];
this.firstListCopY=[];
}
},
//第一层点击
firstChack(falg,item){
if(falg==='down'){
//要展开啦
//展开过程中查看是否已经存在,如果不存在,需要查询二级部门的接口
if(item.children.length===0){
this.getSecondList(item,item.id);
}else{
this.secondFlag = item.id;
this.firstFlag = item.id;
}
}else{
//要关闭啦
this.secondFlag = '';
this.firstFlag = ''
}
},
//获取第一级数据
getFirstList(){
get(`url`).then(data=>{
this.firstAllList = data;
this.firstAllList.forEach(item=>{
//存放二级数据
item.children = [];
//存放children里的被选id,
//用于二级都被选中后联动一级被“选中”;反之,取消一级被选中
item.flagList = [];
})
})
},
//获取第二级数据
getSecondList(item,id){
get(`url/${id}`).then(data=>{
item.children = data;
if(data.length!==0){
this.secondFlag = item.id;
this.firstFlag = item.id;
}
//全选
if(this.radio.length===1){
//如果是全选情况下,展开二级部门,需要进行选中添加
item.children.forEach(them=>{
if(them){
this.secondList.push(them.id);
}
})
}else{
//非全选条件下
//一级已经选择
this.firstList.forEach(them=>{
if(them===item.id){
item.children.forEach(them=>{
if(them){
this.secondList.push(them.id);
}
})
}
})
}
})
},
//一级被点击
firstClick(val){
//添加全选/及反选操作
if(this.firstList.length===this.firstAllList.length){
this.radio = ['1'];
}else{
this.radio = [];
}
if(this.firstListCopY.length>this.firstList.length){
//证明删除了一个一级的
this.firstAllList.forEach(item=>{
if(val===item.id){
item.children.forEach(code=>{
//找到对应一级val的所有二级进行删除
this.secondList.splice(this.secondList.findIndex(item => item=== code.id), 1)
})
}
})
}else{
//证明添加了一个一级的
this.firstAllList.forEach(item=>{
if(val===item.id){
if(item.children){
item.children.forEach(code=>{
let b = this.secondList.indexOf(code.id);
//如果之前该一级部门下的二级没有存在已选列表中,就添加进去
if(b==-1){
this.secondList.push(code.id);
}
})
}
}
})
}
//同步更新,为下次一级被触发时判断使用
this.firstListCopY = JSON.parse(JSON.stringify(this.firstList));
},
//二级被触发
secondClick(){
//每次需要先清空flagList,避免影响下边的逻辑判断
this.firstAllList.forEach(item=>{
item.flagList = [];
})
this.secondList.forEach(item=>{
this.firstAllList.forEach((them)=>{
if(them.children){
them.children.forEach(code=>{
if(item===code.id){
them.flagList.push(code.id);
}
//判断二级是否都被选中,如果全部选中,就将对应的一级添加进已选列表
if(them.flagList.length==them.children.length){
//没有在一级已选列表中找到该点击的二级对应的一级Id-添加进去
let a = this.firstList.indexOf(them.id);
if(a==-1){
this.firstList.push(them.id);
}
}else{
//反之,如果二级没有被全选中,需要去掉对应一级的被选
if(this.firstList.length===0){
return false;
}
this.firstList.forEach((id,i)=>{
if(id===them.id){
this.firstList.splice(i,1);
}
})
}
})
}
})
})
//判断此时是否已经全部选中
if(this.firstList.length===this.firstAllList.length){
this.radio = ['1'];
}else{
this.radio = [];
}
}
},
};
</script>
<style lang="scss" scoped>
.checkAll /deep/ .van-checkbox,
.check_checkThem_first,
.check_checkThem_second{
height: 54px;
border-bottom: 1px solid #ebedf0;//联调完删除
}
.check_checkThem_second{
width:88%;
margin-left:12%;
}
.img{
width:12px;
height:12px;
margin-right:2%;
}
</style>
|