本篇文章将详细讲解 vue3+Element Plus 项目中如何实现el-tree组件的一键全选反选功能:点击一键全选时,将选中所有的节点,当节点未被全部选中时 ,全选框为半选状态。(最后有增加vue2+element ui 实现代码)
vue3+Element Plus具体实现:
模板部分:
1,在合适位置(如el-tree同级)新增一个复选框组件 el-checkbox
<el-checkbox size="mini" :indeterminate="isIndeterminate" v-model="checkAll"
@change="handleCheckAllChange" style="padding:0px;margin-right:5px;">
全选</el-checkbox>
步骤详解:
(1) indeterminate
属性用以表示 checkbox 的不确定状态,一般用于实现全选的效果;
(2)v-model 绑定的值控制全选框是否为选中状态;
(3)@change是状态改变时触发的事件。
2,给el-tree组件绑定ref属性,node-key属性,以及 @check-change事件
<el-tree ref="testingTree" :data="testingData" :props="testingProps"
show-checkbox @check-change="testCheckChange" node-key="path" />
步骤详解:
(1) 在vue3中同样是以ref属性来获取元素;
(2)check-change 事件当复选框被点击的时候触发;
(3)node-key 节点标识 通常用id,实际开发根据后端数据来确定就好。
JS逻辑部分
3,实现全选及反选逻辑(代码有点长,我会逐句讲解)
//一键全选
let checkAll = ref(false) //全选按钮的绑定值
let isIndeterminate = ref(false) //全选按钮的全选,半选样式
const testingTree = ref(null) //在vue3中使用ref获取元素需要在setup中进行声明一个同名变量
//1.1获取当前选中的节点
function testCheckChange() {
// 获取Tree组件的实例,使用ref声明的变量在逻辑代码中使 用时需加 .value
const tree = testingTree.value;
let checkedCount = 0;//被勾选上的一级节点个数
let disabledCount = 0;//置灰的一级节点个数
let indeterminateFlag = false;//有没有一级节点处于半选状态
//遍历所有一级节点(testingData为el-tree组件:data的值)
for (let i = 0; i < testingData.value.length; i++) {
//getNode为el-tree组件的实例方法,可以根据 data 或者 key 拿到 Tree 组件中的 node
if (tree.getNode(testingData.value[i]).disabled == true) {
disabledCount += 1;//如果有置灰的节点,置灰变量加1
}
if (tree.getNode(testingData.value[i]).checked == true) {
checkedCount += 1;//如果有勾选的节点,勾选变量加1
}
if (tree.getNode(testingData.value[i]).indeterminate == true) {
indeterminateFlag = true;//如果有半选的节点,半选变量设为true
}
}
if (checkedCount == 0) {
isIndeterminate.value = false;
checkAll.value = false;//如果勾选的一级节点数为0,则设置全选按钮样式不为半选样式,全选的值为false
if (indeterminateFlag == true) {//如果下面有半选的,设置全选按钮的样式为半选样式
isIndeterminate.value = true;
checkAll.value = false;
}
}
else if ((checkedCount + disabledCount) == testingData.value.length) {//如果树上勾上的和置灰的加起来等于tree上data的长度,设置全选按钮样式不为半选样式,全选值为true
isIndeterminate.value = false;
checkAll.value = true;
}
else {//上面条件不满足,则说明没有全部勾上,设置样式为半选,全选值为false
isIndeterminate.value = true;
checkAll.value = false;
}
return;
}
//全选按钮勾上的方法事件
function handleCheckAllChange(val) {
isIndeterminate.value = false;//设置全选按钮样式不为半选
if (checkAll.value == true) {
//如果是当前值是全选,依次遍历节点设置勾选,同时过滤的disabled为true的
for (let i = 0; i < testingData.value.length; i++) {
if (testingTree.value.getNode(testingData.value[i]).disabled == false) {
testingTree.value.setChecked(testingData.value[i].path, true, true);
}
}
}
else {
//取消全选时置空
testingTree.value.setCheckedKeys([])
}
vue2+Element ui具体实现:
<template>
<div>
<el-checkbox size="mini" :indeterminate="isIndeterminate" v-model="new_task_form.case_checkAll" @change="handleCheckAllChange" style="padding:0px;margin-right:5px;">全选</el-checkbox>
</div>
<el-tree
style="max-height: 200px;overflow: auto;"
:data="casedata"
show-checkbox
:default-expand-all="false"
node-key="id"
ref="casetree"
highlight-current
:props="defaultPorps"
@check-change="case_check_change">
</el-tree>
</template>
data(){
return {
new_task_form:{
"case_checkAll":false //全选按钮的绑定值
},
isIndeterminate:false,//全选按钮的全选,半选样式
}
},
methods:{
case_check_change(node1,node2,node3){//树节点check事件
let checked_count = 0;//被勾选上的一级节点个数
let disabled_count = 0;//置灰的一级节点个数
let indeterminate_flag = false;//有没有一级节点处于半选状态
//遍历所有一级节点
for(let i=0;i<this.casedata.length;i++){
if(this.$refs.casetree.getNode(this.casedata[i]).disabled==true){
disabled_count += 1;//如果有置灰的节点,置灰变量加1
}
if(this.$refs.casetree.getNode(this.casedata[i]).checked==true){
checked_count += 1;//如果有勾选的节点,勾选变量加1
}
if(this.$refs.casetree.getNode(this.casedata[i]).indeterminate==true){
indeterminate_flag = true;//如果有半选的节点,半选变量设为true
}
}
if(checked_count==0){
this.isIndeterminate = false;
this.new_task_form.case_checkAll = false;//如果勾选的一级节点数为0,则设置全选按钮样式不为半选样式,全选的值为false
if(indeterminate_flag==true){//如果下面有半选的,设置全选按钮的样式为半选样式
this.isIndeterminate = true;
this.new_task_form.case_checkAll = false;
}
}
else if((checked_count+disabled_count)==this.casedata.length){//如果树上勾上的和置灰的加起来等于tree上data的长度,设置全选按钮样式不为半选样式,全选值为true
this.isIndeterminate = false;
this.new_task_form.case_checkAll = true;
}
else{//上面条件不满足,则说明没有全部勾上,设置样式为半选,全选值为false
this.isIndeterminate = true;
this.new_task_form.case_checkAll = false;
}
return;
},
handleCheckAllChange(val){//全选按钮勾上的方法事件
this.isIndeterminate = false;//设置全选按钮样式不为半选
if(this.new_task_form.case_checkAll==true){//如果是当前值是全选,依次遍历节点设置勾选,同时过滤的disabled为true的
for(let i=0;i<this.casedata.length;i++){
if(this.$refs.casetree.getNode(this.casedata[i]).disabled==false){
this.$refs.casetree.setChecked(this.casedata[i].id,true,true);
}
}
}
else{//当前值不是全选,设置勾选列表为空
this.$refs.casetree.setCheckedKeys([]);
}
},
}