想必大家在很多时候都会碰到多级复选框的情况吧,下面这篇文章介绍了vue结合el-checkbox组件,编写的一个二级复选框案例(多级也可以根据此案例仿写)。

主要难点:

(1)多次使用v-for循环,把需要展示的复选框按照,一级——二级的样式展现出来。

(2)当一级复选框选中时,二级复选框全选,当二级复选框非全选时,一级复选项为不选中状态,当二级复选框为全选时,一级复选框为选中状态。

(3)全部全选,和全部取消选中。

(4)记录选中的二级复选框id,方便后续操作。

效果图如下:

element table 复选框选中 分页之后就没 element ui复选框_i++

element table 复选框选中 分页之后就没 element ui复选框_i++_02

下面是代码部分:

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>CheckBox二级复选框</title>
		<script src="../vue/vue.min.js" type="text/javascript" charset="utf-8"></script>
		<script src="../elementUI/index.js" type="text/javascript" charset="utf-8"></script>
		<script src="../vue/axios.min.js" type="text/javascript" charset="utf-8"></script>
		<link rel="stylesheet" type="text/css" href="../elementUI/index.css" />
	</head>
	<style type="text/css">
		.checkbox {
			width: 100%;
			height: 100%;
			padding: 0;
			margin: 0;
		}

		.content {
			width: 50%;
			height: 30%;
			margin: 0 auto;
			margin-top: 5%;
		}

		.content .item {
			margin-bottom: 30px;
		}

		.item .oneCheck {
			background-color: #e1e1e1;
		}

		.item .oneCheck .el-checkbox {
			margin-left: 5px;
			padding: 5px;
		}

		.item .oneCheck .el-checkbox__label {
			font-size: 18px;
			font-weight: bold;
		}

		.item .twoCheck {
			margin-left: 30px;
		}

		.footer {
			width: 50%;
			height: 30%;
			padding-top: 20px;
			margin: 0 auto;
		}
	</style>
	<body>
		<div class="checkbox" id="checkbox">
			<div class="content">
				<template v-if="allData != null && allData.length>0">
					<div class="item" v-for="(first,firIndex) in allData" :key="first.oneId">
						<div class="oneCheck">
							<el-checkbox :indeterminate="first.isIndeterminate" v-model="first.mychecked" @change="firstCheck(firIndex,first.oneId)"
							 :label="first.oneName">
								{{first.oneName}}
							</el-checkbox>
						</div>
						<div class="twoCheck">
							<template v-for="(second,secIndex) in first.oneData">
								<el-checkbox v-model="second.mychecked" @change="secondCheck(firIndex,second.twoId)" :label="second.twoName">
									{{second.twoName}}
								</el-checkbox>
							</template>
						</div>
					</div>
				</template>
			</div>
			<div class="footer">
				<el-button type="primary" @click="handleSelectAllChecked">全选</el-button>
				<el-button type="info" @click="handleEmptyAllChecked">清空</el-button>
				<el-button type="success" @click="handleCheckedSure">确认</el-button>
			</div>
		</div>
	</body>
	<script type="text/javascript">
		var vm = new Vue({
			el: '#checkbox',
			data() {
				return {
					allData: [], //所有多选数据

					checkedId: [], //选中的id
					checkedName: [], //选中的name
				};
			},
			methods: {
				/* 获取数据 */
				getCheckBoxData() {
					axios.get('../data/checkboxData.json')
						.then(response => {
							// console.log(response.data);
							if (response.data.code == 0 && response.data.data != null) {
								var result = response.data.data;
								for (var i = 0; i < result.length; i++) {
									result[i]['mychecked'] = false;//一级是否选中
									result[i]['isIndeterminate'] = false;//未全选但已经有了选项的状态
									for (var j = 0; j < result[i].oneData.length; j++) {
										result[i].oneData[j]['mychecked'] = false;//二级是否选中
									}
								}
								this.allData = result;
								console.log(this.allData);
							}
						}).catch(error => {
							console.log(error);
						});
				},
				/* 一级选择事件 */
				firstCheck(index) {
					if (this.allData[index].mychecked == false) {
						this.allData[index].isIndeterminate = false;
						let childrenArray = this.allData[index].oneData;
						if (childrenArray) {
							let len = childrenArray.length;
							for (var i = 0; i < len; i++) {
								childrenArray[i].mychecked = false;
							}
						}
					} else if (this.allData[index].mychecked == true) {
						this.allData[index].isIndeterminate = false;
						let childrenArray = this.allData[index].oneData;
						if (childrenArray) {
							let len = childrenArray.length;
							for (var i = 0; i < len; i++) {
								childrenArray[i].mychecked = true;
							}
						}
					}
				},
				/* 二级选择事件 */
				secondCheck(index) {
					let childrenArray = this.allData[index].oneData;
					let tickCount = 0,
						untickCount = 0,
						len = childrenArray.length;
					for (var i = 0; i < len; i++) {
						if (childrenArray[i].mychecked === true) {
							tickCount++;
						} else {
							untickCount++;
						}
					}
					if (tickCount == len) { //二级全勾选  一级勾选  
						this.allData[index].mychecked = true;
						this.allData[index].isIndeterminate = false;
					} else if (tickCount == 0) { //二级全不勾选 
						this.allData[index].isIndeterminate = false;
					} else { //二级未全选  一级不勾选
						this.allData[index].mychecked = false;
						this.allData[index].isIndeterminate = true;
					}
				},
				/* 全选 */
				handleSelectAllChecked() {
					for (var i = 0; i < this.allData.length; i++) {
						this.allData[i].mychecked = true;
						this.firstCheck(i); //调用一级选择事件
					}
				},
				/* 清空全选 */
				handleEmptyAllChecked() {
					for (var i = 0; i < this.allData.length; i++) {
						this.allData[i].mychecked = false;
						this.allData[i].isIndeterminate = false;
						this.firstCheck(i); //调用一级选择事件
					}
				},
				/* 确认选择 */
				handleCheckedSure() {
					this.checkedId = [];
					this.checkedName = [];
					for (var i = 0; i < this.allData.length; i++) {
						let childrenArray = this.allData[i].oneData;
						let len = childrenArray.length;
						for (var j = 0; j < len; j++) {
							if (childrenArray[j].mychecked == true) {
								this.checkedId.push(childrenArray[j].twoId);
								this.checkedName.push(childrenArray[j].twoName);
							}
						}
					}
					console.log(this.checkedId);
					console.log(this.checkedName);
				}
			},
			mounted() {
				this.getCheckBoxData();
			}
		});
	</script>
</html>

data模拟数据:

{	"code":0,
	"data": [
		{
			"oneId": "1000",
			"oneName": "水果",
			"oneData": [{
					"oneId": "1000",
					"twoId": "1001",
					"twoName": "西瓜"
				},
				{
					"oneId": "1000",
					"twoId": "1002",
					"twoName": "香蕉"
				},
				{
					"oneId": "1000",
					"twoId": "1003",
					"twoName": "苹果"
				}
			]
		},
		{
			"oneId": "2000",
			"oneName": "零食",
			"oneData": [{
					"oneId": "2000",
					"twoId": "2001",
					"twoName": "瓜子"
				},
				{
					"oneId": "2000",
					"twoId": "2002",
					"twoName": "干果"
				},
				{
					"oneId": "2000",
					"twoId": "2003",
					"twoName": "果冻"
				}
			]
		},
		{
			"oneId": "3000",
			"oneName": "奶糖",
			"oneData": [{
					"oneId": "3000",
					"twoId": "3001",
					"twoName": "金丝猴"
				},
				{
					"oneId": "3000",
					"twoId": "3002",
					"twoName": "大白兔"
				},
				{
					"oneId": "3000",
					"twoId": "3003",
					"twoName": "旺仔"
				}
			]
		}
	]
}

讲一下我对难点内容的理解:

(1)如何使用v-for循环,展示一二级复选框。

<template v-for="(second,secIndex) in first.oneData">
@change="secondCheck(firIndex,second.twoId)" :label="second.twoName">
                     {{second.twoName}}
           </el-checkbox></template>
 代码中,我两次使用了<template>标签的模式,在二级el-checkbox的@change方法中,我把一级的firIndex传入其中,目的是为了,当二级复选框全选或者未全选时,可以改变一级复选框的状态。
(2)一级复选框和二级复选框之间的联系。
for (var i = 0; i < result.length; i++) {
      result[i]['mychecked'] = false;//一级是否选中
      result[i]['isIndeterminate'] = false;//未全选但已经有了选项的状态
      for (var j = 0; j < result[i].oneData.length; j++) {
          result[i].oneData[j]['mychecked'] = false;//二级是否选中
     }
 }

 当拿到数据后,我在一级复选内容中添加了两个属性,“mychecked”用来记录是否选中,“isIndeterminate”是el-checkbox中的属性,仅仅改变样式,有选中但是不是全选的状态样式。二级复选中也添加了“mycheckbox”。

在一级选中和未选中时,二级复选框的改变还是相对简单的。只需要使用for循环即可。

在判断二级全选和未全选的时候,要记录一下二级选中的数目,如果等于此二级复选项全部的数目,则改变一级为选中状态。

 

let tickCount = 0,
                         untickCount = 0,
                         len = childrenArray.length;
                     for (var i = 0; i < len; i++) {
                         if (childrenArray[i].mychecked === true) {
                             tickCount++;
                         } else {
                             untickCount++;
                         }
                     }
                     if (tickCount == len) { //二级全勾选  一级勾选  
                         this.allData[index].mychecked = true;
                         this.allData[index].isIndeterminate = false;
                     } else if (tickCount == 0) { //二级全不勾选 
                         this.allData[index].isIndeterminate = false;
                     } else { //二级未全选  一级不勾选
                         this.allData[index].mychecked = false;
                         this.allData[index].isIndeterminate = true;
                     }

(3)全部选中和全部清空。

使用for循环改变一级复选项中的mychecked=true,然后调用一级复选框的方法即可。

for (var i = 0; i < this.allData.length; i++) {
       this.allData[i].mychecked = true;//或者false 要是为false时,记得改变 this.allData[i].isIndeterminate = false;
        this.firstCheck(i); //调用一级选择事件
 }

好了,这次文章就写到这里啦