vue结合element UI做checkbox全选的tree结构

时间:2020-08-08
本文章向大家介绍vue结合element UI做checkbox全选的tree结构,主要包括vue结合element UI做checkbox全选的tree结构使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

由于element UI中的tree可能不能满足项目中的样式需求,所以自己动手结合element中的checkbox全选功能实现了一个符合项目需求的tree。效果如下:

 html部分:

<template>  
    <div class="tree-container">    
        <div v-for="(item,index) in menus" :key="index">      
            <p class="toggleIcon" @click="toggleShow(item)">{{item.isShowAll?'-':'+'}}</p>      
            <el-checkbox :indeterminate="item.isIndeterminate" v-model="item.checkAll" @change="((val)=>{handleCheckAllChange(item,val)})">        
                {{item.name}}      
            </el-checkbox>      
            <span class="checkBox-num">{{item.num}}</span>      
            <el-checkbox-group v-model="item.checkedCities" @change="((val)=>{handleCheckedCitiesChange(item,val)})" class="checkGroup"  v-if="item.isShowAll">        
                <el-checkbox v-for="(it,i) in item.userList" :key="i" :label="it.num" @change="((val)=>{handleCheckedOne(it,val)})">          
                    <label class="icon-zhu" v-if="it.telType == '移动电话' && numList.indexOf(it.num)>=0 ">            
                        <span :class="numList[0] === it.num?'colorful-icon':''"></span>          
                    </label>          
                    <label class="tree-text">
                        {{it.telType}}
                        <span v-if="it.cardType">({{it.cardType}})</span>
                    </label>          
                    <label class="tree-text">{{it.num}}</label>          
                    <label class="tree-text">{{it.label}}</label>        
                </el-checkbox>      
            </el-checkbox-group>    
        </div>  
    </div>
</template>

js部分:

export default {
    name: "Tree",
    props: ["menus", "formData", "numList"],
    methods: {
        // 是否展开checkbox      
        toggleShow(item) {
            item.isShowAll = !item.isShowAll;
        }, handleCheckAllChange(item, val) {
            if (val) {
                item.userList.map(it = > {
                    let numIndex = this.numList.indexOf(it.num);
                    item.checkedCities.push(it.num);
                    this.formData.userNum = Array.from(new Set(this.formData.userNum.concat(item.checkedCities)));
                    if (it.telType == "移动电话") {
                        this.numList.push(it.num);
                    }
                });
            } else {
                item.userList.map(it = > {
                    let Index = this.formData.userNum.indexOf(it.num);
                    let numIndex = this.numList.indexOf(it.num);
                    if (Index > -1) {
                        this.formData.userNum.splice(Index, 1);
                    }
                    if (numIndex > -1) {
                        this.numList.splice(numIndex, 1);
                    }
                });
                item.checkedCities = [];
            }
            item.isIndeterminate = false;
        }, handleCheckedCitiesChange(item, val) {
            let checkedCount = val.length;
            item.checkAll = checkedCount === item.userList.length;
            item.isIndeterminate = checkedCount > 0 && checkedCount < item.userList.length;
        }, handleCheckedOne(item, val) {
            let Index = this.formData.userNum.indexOf(item.num);
            let numIndex = this.numList.indexOf(item.num);
            //如果找到了,有此值        
            if (Index > -1) {
                this.formData.userNum.splice(Index, 1);
            } else {
                this.formData.userNum.push(item.num);
            }
            if (item.telType == "移动电话") {
                if (numIndex > -1) {
                    this.numList.splice(numIndex, 1);
                } else {
                    this.numList.push(item.num);
                }
            }
        }
    }
};

css样式

<style lang="scss" scoped>  @import "../../../assets/css/base.scss";
  .tree-container {
      width: 100%;
      position: relative;
      padding: 10px;
      &>div {      
    margin-left: 20px;
      }

    .toggleIcon {
    width: 14px;
    height: 14px;
    border: 1px solid #dcdcdc;
    @include wordStyle(#dcdcdc, 14px, 600);      text-align: center;
    line-height: 11px;
    cursor: pointer;
    position: absolute;
    left: 10px;
    margin-top: 10px;
    }

    .checkGroup {
    display: flex;
    flex-direction: column;
    padding-left: 20px;
    }
    /deep/ .el-checkbox {
    &+.el-checkbox {        
        margin-left: 0;
    }    
    }
    /deep/ .el-checkbox__inner {
    &: hover {        
        border-color: #ed795a;
    }
    &:focus {
        border: 1px solid #dcdfe6;
        outline: none;
    }    
    }
    /deep/ .el-checkbox__input {
    &.is-checked,&.is-indeterminate {        
        .el-checkbox__inner {          
        background-color: #ed795a;
        border-color: #ed795a;
        }      
    }
    &.is-checked {
        &+.el-checkbox__label {          
            color: #ed795a;
        }      
    }   
    }
    /deep/ .el-checkbox__label {
    font-size: 12px;
    padding-left: 0;
    }
    /deep/ .el-checkbox {
    position: relative;
    }

    .icon-zhu {
    position: absolute;
    left: -24px;
    span {        display: inline-block;
    width: 18px;
    height: 18px;
    line-height: 18px;
    text-align: center;
    border-radius: 100%;
    color: #fff;
    font-weight: bold;
    background-color: #ccc;
    }

    .colorful-icon {
    background-color: #ed795a;
    }  
    .checkBox-num {
    position: absolute;
    right: 10px;
    font-size: 12px;
    }  
}
</style>

数据结构如下

menus: [{
    id: "1",
    name: "不限量173套餐",
    num: "23789446464646",
    checkAll: false,
    checkedCities: [],
    //v-model绑定          
    isIndeterminate: false,
    //设置 indeterminate 状态,只负责样式控制          
    isShowAll: true,
    //控制展开和收缩的状态          
    userList: [{
        id: "1.1",
        username: "html",
        role: "主管",
        telType: "移动电话",
        cardType: "主号",
        label: "现行",
        num: "17316065935"
    }, {
        id: "1.2",
        username: "vue",
        role: "普通",
        telType: "有线宽带",
        cardType: "",
        label: "现行",
        num: "hz87654321"
    }, {
        id: "1.3",
        username: "vue",
        role: "普通",
        telType: "移动电话",
        cardType: "副号",
        label: "现行",
        num: "17316065937"
    }]
}, {
    id: "1",
    name: "不限量199套餐",
    num: "23789446464646",
    checkAll: false,
    checkedCities: [],
    //v-model绑定          
    isIndeterminate: false,
    //设置 indeterminate 状态,只负责样式控制          
    isShowAll: true,
    userList: [{
        id: "1.1",
        username: "html",
        role: "主管",
        telType: "有线宽带",
        cardType: "",
        label: "现行",
        num: "hz1234567"
    }, {
        id: "1.2",
        username: "vue",
        role: "普通",
        telType: "移动电话",
        cardType: "副号",
        label: "现行",
        num: "19916065934"
    }, {
        id: "1.3",
        username: "vue",
        role: "普通",
        telType: "移动电话",
        cardType: "副号",
        label: "现行",
        num: "19916065936"
    }]
}]

原文地址:https://www.cnblogs.com/florazeng/p/13460546.html