vue結合element-ui實現二級復選框checkbox
話不多說先上效果

交互:1、點擊按鈕全選,所有的checkbox全部選中;點擊清空,所有的checkbox框都不選;點擊確定獲取選中的checkbox對應的ID數組
2、點擊右上角的全選,對應的二級都選中,反之都取消選中,當二級都選中時,對應的一級選中
上代碼:
<template>
<div class="checkboxgroup">
<el-button type="primary" @click="handleFilterClassify">點擊篩選品類</el-button>
<el-row>
<el-col :span="24"><p></p><span>選中的id數組:</span><span>{{checkedClassify}}</span></el-col>
</el-row><el-row>
<el-col :span="24"><p><span>選中的name數組:</span><span>{{checkedClassifyName}}</span></p></el-col>
</el-row>
<!-- 當前品類彈窗 -->
<el-dialog
class="filterClassfiy"
title="篩選"
:close-on-click-modal="false"
:visible.sync="dialogVisibleClassify"
width="730px"
>
<div class="wrap">
<div class="title">請選擇要查看的品類</div>
<div class="content">
<template v-if="classifyData!=null && classifyData.length>0">
<div class="item" v-for="(first,firIndex) in classifyData">
<div class="itemHeader">
<div v-cloak>{{first.skillLableName}}</div>
<div class="allCheck">
<el-checkbox
v-model="first.mychecked"
@change="firstChanged(firIndex,first.skillLableId)"
:label="first.skillLableId"
>全選</el-checkbox>
</div>
</div>
<div class="itemContent">
<template
v-for="(second,index2) in first.serviceClassEntitys"
>
<el-checkbox
v-model="second.mychecked"
@change="secondChanged(firIndex,second.serviceClassId)"
:title="second.serviceClassName"
:label="second.serviceClassId"
>{{second.serviceClassName}}</el-checkbox>
</template>
</div>
</div>
</template>
</div>
</div>
<span slot="footer" class="dialog-footer">
<button class="confirm-btn" @click="handleSelectAllClassfiy">全選</button>
<button class="confirm-btn" @click="handleEmptyAllClassfiy">清空</button>
<button class="confirm-btn" @click="handleClassfiySure">確定</button>
</span>
</el-dialog>
</div>
</template>
<script>
export default {
name: "Checkbox",
props: {},
data() {
return {
dialogVisibleClassify: false, //品類彈窗是否顯示
classifyData: [], //當前所有品類數組
checkedClassify: [], //選中的品類Id數組
checkedClassifyName: [] //選中的品類名稱數組
};
},
mounted() {
//獲取品類數據
this.getClassifyData();
},
methods: {
getClassifyData() {
this.axios
.get(
"https://www.easy-mock.com/mock/5cda38699ef682599c4736c7/esmart/monitor/getServiceClass"
)
.then(res => {
console.log(res)
if (res.data.code == 0 && res.data.data !== null) {
var result = res.data.data;
for (var i = 0; i < result.length; i++) {
result[i]["mychecked"] = false;
for (var j = 0; j < result[i].serviceClassEntitys.length; j++) {
result[i].serviceClassEntitys[j]["mychecked"] = false;
}
}
this.classifyData = result;
}
})
.catch(err => {
console.log(err);
});
},
//點擊品類篩選
handleFilterClassify() {
this.dialogVisibleClassify = true;
},
//品類彈框選擇所有
handleSelectAllClassfiy: function () {
for (var i = 0; i < this.classifyData.length; i++) {
this.classifyData[i].mychecked = true;
this.firstChanged(i); //調用一級change事件
}
},
// 一級change事件
firstChanged: function(index) {
//一級未選中 則對應的二級都不選中
if (this.classifyData[index].mychecked == false) {
var childrenArray = this.classifyData[index].serviceClassEntitys;
if (childrenArray) {
for (var i = 0, len = childrenArray.length; i < len; i++) {
childrenArray[i].mychecked = false;
}
}
//一級選中 則對應的二級都選中
} else if (this.classifyData[index].mychecked = true) {
var childrenArray = this.classifyData[index].serviceClassEntitys;
if (childrenArray) {
for (var i = 0, len = childrenArray.length; i < len; i++) {
childrenArray[i].mychecked = true;
}
}
}
},
//二級change事件
secondChanged: function (firIndex) {
var childrenArray = this.classifyData[firIndex].serviceClassEntitys;
var tickCount = 0,
unTickCount = 0,
len = childrenArray.length
for (var i = 0; i < len; i++) {
if (childrenArray[i].mychecked == true) {
tickCount++;
}
if (childrenArray[i].mychecked == false) {
unTickCount++;
}
}
if (tickCount == len) { //二級全勾選 一級勾選
this.classifyData[firIndex].mychecked = true;
} else {//二級未全選 一級不勾選
this.classifyData[firIndex].mychecked = false;
}
},
//品類彈框清空所有
handleEmptyAllClassfiy:function(){
for(var i=0;i<this.classifyData.length;i++){
for(var j=0;j<this.classifyData.length;j++){
this.classifyData[i].mychecked=false;
this.firstChanged(i)//調用一級change事件
}
}
},
////品類篩選關閉
handleClassfiySure: function () {
this.checkedClassify = [];
this.checkedClassifyName = [];
//對classifyData處理給checkedClassify和checkedClassifyName賦值
for (var i = 0; i < this.classifyData.length; i++) {
var serviceClassEntitys = this.classifyData[i].serviceClassEntitys;
var len = serviceClassEntitys.length;
for (var j = 0; j < len; j++) {
if (serviceClassEntitys[j].mychecked==true) {
this.checkedClassify.push(serviceClassEntitys[j].serviceClassId);
this.checkedClassifyName.push(serviceClassEntitys[j].serviceClassName)
}
}
}
//判斷勾選的品類是否為空,為空的話顯示全部
if (this.checkedClassify.length==0) {
for (var i = 0; i < this.classifyData.length; i++) {
var serviceClassEntitys = this.classifyData[i].serviceClassEntitys
for (var j = 0; j < serviceClassEntitys.length; j++) {
this.checkedClassifyName.push(serviceClassEntitys[j].serviceClassName);
}
}
}
console.log(this.checkedClassify,this.checkedClassifyName);
this.dialogVisibleClassify = false;//關閉彈窗
},
}
};
</script>
<style scope>
/* 當前品類彈框 */
.el-dialog {
width: 730px !important;
height: 577px !important;
background-color: #18202a;
box-shadow: 0px 2px 12px 0px rgba(0, 0, 0, 0.06);
}
.filterClassfiy .el-dialog__body {
padding: 20px 30px;
}
.el-dialog .el-dialog__title{
color: #fff;
}
.filterClassfiy .wrap .title {
font-size: 16px;
color: #acacac;
margin: 5px;
}
.filterClassfiy .wrap .content {
width: 630px;
height: 355px;
padding: 20px;
overflow-y: auto;
color: #fff;
background-color: rgba(0, 0, 0, 0.2);
}
.filterClassfiy .wrap .content::-webkit-scrollbar {
display: none;
}
.filterClassfiy .itemContent .el-checkbox {
color: #fff;
font-size: 12px;
margin: 5px;
width: 31%;
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
}
.filterClassfiy .wrap .content .el-checkbox__label {
padding-left: 6px;
}
.filterClassfiy .wrap .content .itemHeader {
font-size: 14px;
display: flex;
justify-content: space-between;
align-items: center;
margin: 5px;
}
.filterClassfiy .wrap .content .itemHeader .el-checkbox {
width: 25%;
color: #fff;
}
.filterClassfiy .wrap .content .itemHeader .el-checkbox__inner {
left: 54px;
}
.filterClassfiy .wrap .content .itemHeader .allCheck {
font-size: 12px;
display: flex;
width: 70px;
align-items: center;
}
.filterClassfiy .wrap .content .itemHeader .allCheck span {
display: inline-block;
}
.filterClassfiy .wrap .content .itemContent {
background-color: #232b34;
padding: 10px 20px 0;
}
.confirm-btn{
width: 100px;
height: 29px;
color: #fff;
background: rgba(0, 131, 247, 0.5);
font-size: 14px;
outline: none;
border: 0;
cursor: pointer
}
.el-dialog__footer{
text-align: center
}
</style>
