vue基于element-ui的三级CheckBox复选框功能的实现代码


Posted in Javascript onOctober 15, 2018

最近vue项目需要用到三级CheckBox复选框,需要实现全选反选不确定三种状态。但是element-ui table只支持多选行,并不能支持三级及以上的多选,下面通过本文给大家讲解实现方法。

效果图预览:

vue基于element-ui的三级CheckBox复选框功能的实现代码

首先是页面布局,当然也可已使用table,但是自己用flex布局后面更容易增删改查其他功能

<div class="deliverySetting-table">
      <div class="table-head">
        <div class="selection">
          <el-checkbox :indeterminate="indeterminate" v-model="ischeckAll" @change="handleCheckAllChange"></el-checkbox>
        </div>
        <div class="width185">分区名称</div>
        <div class="width265">国家</div>
        <div>派送商</div>
      </div>
      <div class="table-body" v-for="(partition,partitionIndex) in distributorsInfo" :key="partitionIndex">
        <div class="selection">
          <p><el-checkbox :indeterminate="partition.indeterminate" v-model="partition.selected" @change="handleCheckedCountryAllChange(partitionIndex,partition.partitionId,$event)" :key="partitionIndex"></el-checkbox></p>
        </div>
        <div class="width185"><p>{{ partition.partitionName }}</p></div>
        <div class="width265">
          <el-checkbox v-for="country in partition.country" v-model="country.selected" @change="handleCheckedCountryChange(partitionIndex,country.id,partition.partitionId,$event)" :label="country" :key="country.id">{{country.fieldName}}</el-checkbox>
        </div>
        <div>
          <p v-for="(item,index) in partition.country" :key="index">
            {{ item.distributors }}
          </p>
        </div>
      </div>
    </div>

接下来是数据结构,自定义的,可以更后台商议,但是字段indeterminate(显示不确定状态~符号),selected(CheckBox选中状态)一定要让后台加入到data中,其他可以按照后台数据来。

distributorsInfo:[
          { partitionName:'1区',selected:false,partitionId:1,isIndeterminate:false,
            country:[
            {  id: "1",fieldName: "奥地利",fieldTableName: "奥地利",distributors:'UPS',selected: false},
            {  id: "2",fieldName: "芬兰",fieldTableName: "芬兰",distributors:'UPS',selected: false},
            {  id: "3",fieldName: "意大利",fieldTableName: "意大利",distributors:'UPS',selected: false},
            {  id: "4",fieldName: "葡萄牙",fieldTableName: "葡萄牙",distributors:'UPS',selected: false},
            {  id: "9",fieldName: "西班牙",fieldTableName: "西班牙",distributors:'UPS',selected: false},
            {  id: "10",fieldName: "瑞典",fieldTableName: "瑞典",distributors:'UPS',selected: false},]
          },
          { partitionName:'2区',selected:false,partitionId:2,isIndeterminate:false,
            country:[
            {  id: "5",fieldName: "丹麦",fieldTableName: "单买",distributors:'',selected: false},
            {  id: "6",fieldName: "法国",fieldTableName: "法国",distributors:'',selected: false},]
          },
          { partitionName:'3区',selected:false,partitionId:3,isIndeterminate:false,
            country:[
            {  id: "7",fieldName: "德国",fieldTableName: "德国",distributors:'YODEL',selected: false},
            {  id: "8",fieldName: "瑞士",fieldTableName: "瑞士",distributors:'DPD',selected: false}]
          }
        ],
        ischeckAll:false,//一级全选状态

因为此处是三级复选,所以函数为三个change,具体有详细注释可以查看

handleCheckAllChange(e){//一级change事件
        this.ischeckAll = e
        if(e == true){
          this.indeterminate = false
          for(var i=0,len=this.distributorsInfo.length; i<len; i++){ //二级全选反选不确定
            this.distributorsInfo[i].selected = e
            for(var j=0,len1=this.distributorsInfo[i].country.length; j<len1; j++){
              this.distributorsInfo[i].country[j].selected = e
            }
          }
        }else{
          this.indeterminate = false
          for(var i=0,len=this.distributorsInfo.length; i<len; i++){ //三级全选反选不确定
            this.distributorsInfo[i].selected = e
            for(var j=0,len1=this.distributorsInfo[i].country.length; j<len1; j++){
              this.distributorsInfo[i].country[j].selected = e
            }
          }
        }
      },
      handleCheckedCountryAllChange(index, topId, e){//二级change事件
        this.distributorsInfo[index].selected = e//二级勾选后,子级全部勾选或者取消
        if(e == false) this.distributorsInfo[index].indeterminate = false //去掉二级不确定状态
        var childrenArray = this.distributorsInfo[index].country
        if(childrenArray)
          for(var i=0,len=childrenArray.length; i<len; i++)
            childrenArray[i].selected = e

        this.getIsCheckAll()
      },
      handleCheckedCountryChange(topIndex, sonId, topId, e){//三级change事件
        var childrenArray = this.distributorsInfo[topIndex].country
        var tickCount = 0, unTickCount = 0, len = childrenArray.length
        for(var i = 0; i < len; i++){
          if(sonId == childrenArray[i].id) childrenArray[i].selected = e
          if(childrenArray[i].selected == true) tickCount++
          if(childrenArray[i].selected == false) unTickCount++
        }
        if(tickCount == len) {//三级级全勾选
          this.distributorsInfo[topIndex].selected = true 
          this.distributorsInfo[topIndex].indeterminate = false
        } else if(unTickCount == len) {//三级级全不勾选
          this.distributorsInfo[topIndex].selected = false 
          this.distributorsInfo[topIndex].indeterminate = false
        } else {
          this.distributorsInfo[topIndex].selected = false
          this.distributorsInfo[topIndex].indeterminate = true //添加二级不确定状态
        }

        this.getIsCheckAll()
      },
      getIsCheckAll(){
        var tickCount = 0, unTickCount = 0, ArrLength = this.distributorsInfo.length
        for(var j=0; j<ArrLength; j++){//全选checkbox状态
          if(this.distributorsInfo[j].selected == true) tickCount++
          if(this.distributorsInfo[j].selected == false) unTickCount++
        }
        if(tickCount == ArrLength) {//二级全勾选
          this.ischeckAll = true
          this.indeterminate = false
        } else if(unTickCount == ArrLength) {//二级全不勾选
          this.ischeckAll = false
          this.indeterminate = false
        } else {
          this.ischeckAll = false
          this.indeterminate = true //添加一级不确定状态
        }
      },

以下是页面完整组件代码可以使用预览

<template>
  <div class="deliverySetting">
    <div class="deliverySetting-btn">
      <div class="tabs-btn ac">
        <input type="button" value="分配派送商" @click="showSetDistributorDailog">
      </div>
      <div class="tabs-btn ac">
        <input type="button" value="取消分配" @click="showCancelDistributorDailog">
      </div>
    </div>

    <div class="deliverySetting-table">
      <div class="table-head">
        <div class="selection">
          <el-checkbox :indeterminate="indeterminate" v-model="ischeckAll" @change="handleCheckAllChange"></el-checkbox>
        </div>
        <div class="width185">分区名称</div>
        <div class="width265">国家</div>
        <div>派送商</div>
      </div>
      <div class="table-body" v-for="(partition,partitionIndex) in distributorsInfo" :key="partitionIndex">
        <div class="selection">
          <p><el-checkbox :indeterminate="partition.indeterminate" v-model="partition.selected" @change="handleCheckedCountryAllChange(partitionIndex,partition.partitionId,$event)" :key="partitionIndex"></el-checkbox></p>
        </div>
        <div class="width185"><p>{{ partition.partitionName }}</p></div>
        <div class="width265">
          <el-checkbox v-for="country in partition.country" v-model="country.selected" @change="handleCheckedCountryChange(partitionIndex,country.id,partition.partitionId,$event)" :label="country" :key="country.id">{{country.fieldName}}</el-checkbox>
        </div>
        <div>
          <p v-for="(item,index) in partition.country" :key="index">
            {{ item.distributors }}
          </p>
        </div>
      </div>
    </div>

    <!-- 分配派送商dailog -->
    <el-dialog title="分配派送商" :visible.sync="setDistributorDailog" width="480px">
      <el-form :model="distributorForm" :rules="rules" class="setDistributorDailog">
        <el-form-item label="派送代理商" label-width="120px">
          <el-input v-model="distributorForm.vendorName" auto-complete="off" placeholder="请输入供应商名称"></el-input>
        </el-form-item>
        <el-form-item label="末端派送商" prop="senderName" label-width="120px">
          <el-select v-model="distributorForm.senderName"
          filterable
          allow-create
          default-first-option
          placeholder="请选派送商名称">
            <el-option label="派送商1" value="shanghai"></el-option>
            <el-option label="派送商2" value="beijing"></el-option>
          </el-select>
        </el-form-item>
        <el-form-item label="派送商官网" prop="website" label-width="120px">
          <el-input v-model="distributorForm.website" auto-complete="off" placeholder="请输入派送商官网"></el-input>
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button @click="setDistributorDailog = false">取 消</el-button>
        <el-button type="primary" @click="setDistributorDailog = false">确 定</el-button>
      </div>
    </el-dialog>

    <!-- 取消分配派送商 -->
    <el-dialog title="停止提示" :visible.sync="cancelDistributorDailog" :modal="false" width="480px" custom-class="stop-coupon-dialog">
      <p><br></p>
      <p class="ac f16">您确定要取消对的派送分配吗?</p>
      <p><br></p>
      <span slot="footer" class="dialog-footer">
        <el-button @click="cancelDistributorDailog = false">取 消</el-button>
        <el-button type="primary" @click="cancelDistributorDailog=false">确 定</el-button>
      </span>
    </el-dialog>
  </div>
</template>
<script>
  export default {
    name:'deliverySetting',
    components: {
    },
    props:{
    },
    data() {
      return {
        distributorsInfo:[
          { partitionName:'1区',selected:false,partitionId:1,isIndeterminate:false,
            country:[
            {  id: "1",fieldName: "奥地利",fieldTableName: "奥地利",distributors:'UPS',selected: false},
            {  id: "2",fieldName: "芬兰",fieldTableName: "芬兰",distributors:'UPS',selected: false},
            {  id: "3",fieldName: "意大利",fieldTableName: "意大利",distributors:'UPS',selected: false},
            {  id: "4",fieldName: "葡萄牙",fieldTableName: "葡萄牙",distributors:'UPS',selected: false},
            {  id: "9",fieldName: "西班牙",fieldTableName: "西班牙",distributors:'UPS',selected: false},
            {  id: "10",fieldName: "瑞典",fieldTableName: "瑞典",distributors:'UPS',selected: false},]
          },
          { partitionName:'2区',selected:false,partitionId:2,isIndeterminate:false,
            country:[
            {  id: "5",fieldName: "丹麦",fieldTableName: "单买",distributors:'',selected: false},
            {  id: "6",fieldName: "法国",fieldTableName: "法国",distributors:'',selected: false},]
          },
          { partitionName:'3区',selected:false,partitionId:3,isIndeterminate:false,
            country:[
            {  id: "7",fieldName: "德国",fieldTableName: "德国",distributors:'YODEL',selected: false},
            {  id: "8",fieldName: "瑞士",fieldTableName: "瑞士",distributors:'DPD',selected: false}]
          }
        ],
        ischeckAll:false,//一级全选状态
        setDistributorDailog:false,
        cancelDistributorDailog:false,
        distributorForm:{
          vendorName:'',
          senderName:''
        },
        indeterminate:false,
        rules: {
          senderName: [{ required: true, message: '字段不能为空',trigger: 'blur'}],
          website: [{ required: true, message: '字段不能为空',trigger: 'blur'}],
        },
      }
    },
    computed: {
    },
    methods: {
      handleCheckAllChange(e){//一级change事件
        this.ischeckAll = e
        if(e == true){
          this.indeterminate = false
          for(var i=0,len=this.distributorsInfo.length; i<len; i++){ //二级全选反选不确定
            this.distributorsInfo[i].selected = e
            for(var j=0,len1=this.distributorsInfo[i].country.length; j<len1; j++){
              this.distributorsInfo[i].country[j].selected = e
            }
          }
        }else{
          this.indeterminate = false
          for(var i=0,len=this.distributorsInfo.length; i<len; i++){ //三级全选反选不确定
            this.distributorsInfo[i].selected = e
            for(var j=0,len1=this.distributorsInfo[i].country.length; j<len1; j++){
              this.distributorsInfo[i].country[j].selected = e
            }
          }
        }
      },
      handleCheckedCountryAllChange(index, topId, e){//二级change事件
        this.distributorsInfo[index].selected = e//二级勾选后,子级全部勾选或者取消
        if(e == false) this.distributorsInfo[index].indeterminate = false //去掉二级不确定状态
        var childrenArray = this.distributorsInfo[index].country
        if(childrenArray)
          for(var i=0,len=childrenArray.length; i<len; i++)
            childrenArray[i].selected = e

        this.getIsCheckAll()
      },
      handleCheckedCountryChange(topIndex, sonId, topId, e){//三级change事件
        var childrenArray = this.distributorsInfo[topIndex].country
        var tickCount = 0, unTickCount = 0, len = childrenArray.length
        for(var i = 0; i < len; i++){
          if(sonId == childrenArray[i].id) childrenArray[i].selected = e
          if(childrenArray[i].selected == true) tickCount++
          if(childrenArray[i].selected == false) unTickCount++
        }
        if(tickCount == len) {//三级级全勾选
          this.distributorsInfo[topIndex].selected = true 
          this.distributorsInfo[topIndex].indeterminate = false
        } else if(unTickCount == len) {//三级级全不勾选
          this.distributorsInfo[topIndex].selected = false 
          this.distributorsInfo[topIndex].indeterminate = false
        } else {
          this.distributorsInfo[topIndex].selected = false
          this.distributorsInfo[topIndex].indeterminate = true //添加二级不确定状态
        }

        this.getIsCheckAll()
      },
      getIsCheckAll(){
        var tickCount = 0, unTickCount = 0, ArrLength = this.distributorsInfo.length
        for(var j=0; j<ArrLength; j++){//全选checkbox状态
          if(this.distributorsInfo[j].selected == true) tickCount++
          if(this.distributorsInfo[j].selected == false) unTickCount++
        }
        if(tickCount == ArrLength) {//二级全勾选
          this.ischeckAll = true
          this.indeterminate = false
        } else if(unTickCount == ArrLength) {//二级全不勾选
          this.ischeckAll = false
          this.indeterminate = false
        } else {
          this.ischeckAll = false
          this.indeterminate = true //添加一级不确定状态
        }
      },

      showSetDistributorDailog(){
        this.setDistributorDailog=true
      },
      showCancelDistributorDailog(){
        this.cancelDistributorDailog=true
      }
    },
    created: function() {
    },
    mounted: function() {
      // (async() => {
    },
    watch: {
    }
  }
</script>
<style lang="scss">
.deliverySetting{
  padding: 20px 0;
  position: relative;
  .el-table{
    thead{
      tr{
        th{
          font-size: 14px;
        }
      }
    }
    tbody{
      tr{
        td{
          vertical-align: baseline;
          p{
            line-height: 30px;
          }
          .el-checkbox-group{
            display: flex;
            flex-direction: column;
            label{
              line-height: 30px;
              margin-left: 0;
            }
          }
        }
      }
    }
  }
  .deliverySetting-table{
    font-size: 14px;
    color: #333;
    .table-head,
    .table-body{
      display: flex;
      padding: 10px 0;
      .selection{
        width: 45px;
        text-align: center;
        line-height: 36px;
      }
      .width185{
        width: 185px;
      }
      .width265{
        width: 265px;
      }
    }
    .table-head{
      height: 36px;
      align-items: center;
      background-color: #E7F2FF;
    }
    .table-body{
      border-bottom: 1px solid #e4e4e4;
      color: #666;
      &:hover{
        background-color: #f5f7fa;
      }
      .width265{
        display: flex;
        flex-direction: column;
        label{
          line-height: 30px;
          margin-left: 0;
          color: #666;
        }
      }
      p{
        line-height: 30px;
      }
    }
  }
  .deliverySetting-btn{
    /*width: 100%;*/
    height: 59px;
    display: flex;
    justify-content: flex-end;
    align-items: center;
    position: absolute;
    top: -55px;
    right: -16px;
    z-index: 100;
    .tabs-btn {
      min-width: 90px;
      height: 34px;
      line-height: 32px;
      padding: 0 10px;
      color: #2387f7;
      border: solid 1px #4fa2ff;
      background-color: #e7f2ff;
      cursor: pointer;
      &:nth-of-type(2) {
        margin: 0 15px;
      }
      input {
        border: none;
        background: transparent;
        color: inherit;
        cursor: inherit;
        outline: none;
        margin: 0;
        padding: 0;
      }
      &:hover {
        color: #fff;
        background-color: #2387f7;
      }
    }
  }
  .setDistributorDailog{
    .el-input{
      width: 270px;
    }
  }
}
</style>

好了,以后使用三级甚至多级复选都可以使用此方法添加change代码即可。

总结

以上所述是小编给大家介绍的vue基于element-ui的三级CheckBox复选框功能的实现代码,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!

Javascript 相关文章推荐
JavaScript版代码高亮
Jun 26 Javascript
js 强制弹出窗口代码研究-又一款代码
Mar 20 Javascript
jquery子元素过滤选择器使用示例
Jun 24 Javascript
JS将所有对象s的属性复制给对象r(原生js+jquery)
Jan 25 Javascript
浅谈使用MVC模式进行JavaScript程序开发
Nov 10 Javascript
jQuery禁用快捷键例如禁用F5刷新 禁用右键菜单等的简单实现
Aug 31 Javascript
KVM虚拟化技术之使用Qemu-kvm创建和管理虚拟机的方法
Oct 05 Javascript
EasyUI在Panel上动态添加LinkButton按钮
Aug 11 Javascript
JS基于for语句编写的九九乘法表示例
Jan 04 Javascript
Node.js实现注册邮箱激活功能的方法示例
Mar 23 Javascript
微信小程序form表单组件示例代码
Jul 15 Javascript
vue 组件内获取actions的response方式
Nov 08 Javascript
vue+axios+promise实际开发用法详解
Oct 15 #Javascript
javascript中关于类型判断的一些疑惑小结
Oct 14 #Javascript
JS面试题大坑之隐式类型转换实例代码
Oct 14 #Javascript
JS中appendChild追加子节点无效的解决方法
Oct 14 #Javascript
详解ES6 Symbol 的用途
Oct 14 #Javascript
javascript实现文本框标签验证的实例代码
Oct 14 #Javascript
Vue+webpack项目配置便于维护的目录结构教程详解
Oct 14 #Javascript
You might like
PHP 常用数组内部函数(Array Functions)介绍
2013/06/05 PHP
PHP处理JSON字符串key缺少双引号的解决方法
2014/09/16 PHP
UPUPW 更新 64 位 Apache 系列 PHP 7.0 正式版
2015/12/08 PHP
PHP基于回溯算法解决n皇后问题的方法示例
2017/11/07 PHP
javascript一些不错的函数脚本代码
2008/09/10 Javascript
JavaScript的parseInt 取整使用
2011/05/09 Javascript
新发现一个骗链接的方法(js读取cookies)
2012/01/11 Javascript
jquery 操作两个select实现值之间的互相传递
2014/03/07 Javascript
JS函数this的用法实例分析
2015/02/05 Javascript
实例剖析AngularJS框架中数据的双向绑定运用
2016/03/04 Javascript
jQuery学习笔记——jqGrid的使用记录(实现分页、搜索功能)
2016/11/09 Javascript
CSS+jQuery实现简单的折叠菜单
2016/12/20 Javascript
使用AngularJS2中的指令实现按钮的切换效果
2017/03/27 Javascript
layui.js实现的表单验证功能示例
2017/11/15 Javascript
详解vue2.0 不同屏幕适配及px与rem转换问题
2018/02/23 Javascript
element-ui 中的table的列隐藏问题解决
2018/08/24 Javascript
vue.js实现h5机器人聊天(测试版)
2020/07/16 Javascript
详解node.js创建一个web服务器(Server)的详细步骤
2021/01/15 Javascript
[00:32]2018DOTA2亚洲邀请赛出场——VP
2018/04/04 DOTA
[01:10:27]DOTA2-DPC中国联赛正赛 SAG vs XG BO3 第二场 3月5日
2021/03/11 DOTA
Python随机数random模块使用指南
2016/09/09 Python
python smtplib模块自动收发邮件功能(二)
2018/05/22 Python
对python实现二维函数高次拟合的示例详解
2018/12/29 Python
python opencv 读取本地视频文件 修改ffmpeg的方法
2019/01/26 Python
Python分割训练集和测试集的方法示例
2019/09/19 Python
Python sklearn库实现PCA教程(以鸢尾花分类为例)
2020/02/24 Python
Jupyter notebook 启动闪退问题的解决
2020/04/13 Python
美国职棒大联盟官方网上商店:MLBShop.com
2017/11/12 全球购物
Overload和Override的区别。Overloaded的方法是否可以改变返回值的类型
2013/10/30 面试题
志愿者活动总结
2014/04/28 职场文书
写得不错的求职信范文
2014/07/11 职场文书
学校机关党总支领导班子整改工作方案
2014/10/26 职场文书
国庆节慰问信
2015/02/15 职场文书
婚庆开业庆典主持词
2015/06/30 职场文书
spring boot项目application.properties文件存放及使用介绍
2021/06/30 Java/Android
mybatis 获取无数据的字段不显示的问题
2021/07/15 Java/Android