el-tree 树增加全选按钮、点击文字时选中多选框

最近,用到el-tree这个插件,发现elementui里面没有我想要要的那种样式,自己就做了一个记录一下,点击全选时,所有选项都会选中,当没有全选上时,全选前面的多现框会是半选状态,el-tree数据里面需要有‘disabled: false’这参数记录,需要需要记录一下,当前节点是否可选,
实现过程,先添加一个全选的多选框,点击全选时,设置全选按钮样式不为半选,如果是当前值是全选,依次遍历节点设置勾选,同时过滤的disabled为true的,当前值不是全选,设置勾选列表为空,点击树节点时,记录树节点的三种状态(是否可选、勾选、半选、)然后判断,如果勾选的一级节点数为0,则设置全选按钮样式不为半选样式,全选的值为false,如果下面有半选的,设置全选按钮的样式为半选样式。如果树上勾上的和置灰的加起来等于tree上data的长度,设置全选按钮样式不为半选样式,全选值为true。如果条件不满足,则说明没有全部勾上,设置样式为半选,全选值为false。

今天(2022/11/18)修改改了一下,把data循环修改成了深度循环,因为当check-strictly为true时,全选就会出现bug,所以改成深度循环。(check-strictly:在显示复选框的情况下,是否严格的遵循父子不互相关联的做法,默认为 false),如果check-strictly为false时下面有置灰状态,全选为半选状态,如果check-strictly为true时下面有置灰状态,全选为全选状态。

设置点击文字切换选中状态时:
el-tree标签内加上:check-on-click-node

设置多选:
el-tree标签加上:show-checkbox

取消勾选:
this.$refs.casetree.setCheckedKeys([]);

在这里插入图片描述

<template>
    <div>
        <div>
        <el-checkbox 
            size="mini" 
            :indeterminate="isIndeterminate"  
            v-model="caseCheckAll" 
            @change="handleCheckAllChange" 
        >全选</el-checkbox>
        </div>
        <el-tree
            :data="data"
            show-checkbox
            :default-expand-all="true"
            node-key="id"
            ref="casetree"
            highlight-current
            :check-strictly="true"
            :props="defaultPorps"
            :check-on-click-node="true"
            @check-change="caseCheckChange"
        >
            <span class="custom-tree-node" slot-scope="{node,data }">
                <span v-if="data.children.length > 0">
                    <span class="treeText1" @click="() => append(data)">
                        <i class="el-icon-edit"  icon-class="tag"  :w="13"  :h="13" ></i>
                        {{node.label}}
                    </span>
                </span>
                <span v-else>
                    {{node.label}}
                </span>
            </span>
        </el-tree>
    </div>
  </template>
<script>
    export default {
        data(){
            return {
                data: [
                    {
                        id: 1,
                        label: '一级 1',
                        disabled: false,
                        children: [{
                            id: 3,
                            label: '二级 2-1',
                            disabled: false,
                            children: [{
                                id: 4,
                                label: '三级 3-1-1',
                                disabled: false,
                                children: [],
                            }, {
                                id: 5,
                                label: '三级 3-1-2',
                                disabled: true,
                                children: [],
                            }]
                        }, {
                            id: 2,
                            label: '二级 2-2',
                            disabled: false,
                            children: [{
                                id: 6,
                                label: '三级 3-2-1',
                                disabled: false,
                                children: []
                            }, {
                                id: 7,
                                label: '三级 3-2-2',
                                disabled: false,
                                children: []
                            }]
                        }]
                    },{
                        id: 9,
                        label: '一级 2',
                        children: [],
                        disabled: false,
                    }
                ],
                defaultPorps: {
                    children: 'children',
                    label: 'label'
                },
                caseCheckAll:false, //全选按钮的绑定值
                isIndeterminate:false, //全选按钮的全选,半选样式 
            }
        },
        methods:{
            caseCheckChange(){ //树节点check事件
                let checked_count = 0; //被勾选上的一级节点个数
                let disabled_count = 0; //置灰的一级节点个数
                let indeterminate_flag = false; //有没有一级节点处于半选状态
                // 深度遍历所有一级节点
                var numArray = [];
                let stack = [...this.data], node;
                while (node = stack.shift()) {
                    numArray.push(node.id)
                    if(this.$refs.casetree.getNode(node).disabled==true){
                        disabled_count += 1;//如果有置灰的节点,置灰变量加1
                    }
                    if(this.$refs.casetree.getNode(node).checked==true){
                        checked_count += 1;//如果有勾选的节点,勾选变量加1
                    }
                    if(this.$refs.casetree.getNode(node).indeterminate==true){
                        indeterminate_flag = true;//如果有半选的节点,半选变量设为true
                    }
                    // 如果有子元素的话进行压栈操作
                    if (node.children) stack.unshift(...node.children)
                }
                if(checked_count==0){
                    this.isIndeterminate = false;
                    this.caseCheckAll = false; //如果勾选的一级节点数为0,则设置全选按钮样式不为半选样式,全选的值为false
                    if(indeterminate_flag == true){ //如果下面有半选的,设置全选按钮的样式为半选样式
                        this.isIndeterminate = true;
                        this.caseCheckAll = false;
                    }    
                }else if((checked_count+disabled_count) == numArray.length){ //如果树上勾上的和置灰的加起来等于tree上data的长度,设置全选按钮样式不为半选样式,全选值为true
                    this.isIndeterminate = false;
                    this.caseCheckAll = true;
                }else{ //上面条件不满足,则说明没有全部勾上,设置样式为半选,全选值为false
                    this.isIndeterminate = true;
                    this.caseCheckAll = false;
                }
                return;
            },
            handleCheckAllChange(){ //全选按钮勾上的方法事件
                this.isIndeterminate = false; //设置全选按钮样式不为半选
                if(this.caseCheckAll == true){ //如果是当前值是全选,依次遍历节点设置勾选,同时过滤的disabled为true的
                    // 深度遍历
                    let stack = [...this.data], node;
                    while (node = stack.shift()) {
                        console.log(node.id);
                        if(this.$refs.casetree.getNode(node).disabled==false){
                            this.$refs.casetree.setChecked(node.id,true,true);
                        }
                        // 如果有子元素的话进行压栈操作
                        if (node.children) stack.unshift(...node.children)
                    }   
                }else{ //当前值不是全选,设置勾选列表为空
                    this.$refs.casetree.setCheckedKeys([]);
                }  
            }, 
            append(value){
                console.log(value)
            }  
        }
    }
</script>

参考文献:
el-tree实现全选(子节点选择同时反向影响全选按钮)
el-tree组件展示节点过多时造成页面卡顿、奔溃的解决办法
js中树形结构的深度遍历与广度遍历

  • 3
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值