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 相关文章推荐
Lazy Load 延迟加载图片的 jQuery 插件
Feb 06 Javascript
小议Javascript中的this指针
Mar 18 Javascript
jQuery EasyUI Pagination实现分页的常用方法
May 21 Javascript
jquery层级选择器(匹配父元素下的子元素实现代码)
Sep 05 Javascript
微信公众号 客服接口的开发实例详解
Sep 28 Javascript
jQuery插件FusionCharts实现的2D饼状图效果【附demo源码下载】
Mar 03 Javascript
老生常谈javascript的面向对象思想
Aug 22 Javascript
如何使用 vue + d3 画一棵树
Dec 03 Javascript
详解如何为你的angular app构建一个第三方库
Dec 07 Javascript
js设计模式之代理模式及订阅发布模式实例详解
Aug 15 Javascript
node.js中对Event Loop事件循环的理解与应用实例分析
Feb 14 Javascript
JavaScript实现点击切换验证码及校验
Jan 10 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常用ODBC函数集(详细)
2013/06/24 PHP
WordPress开发中用于获取近期文章的PHP函数使用解析
2016/01/05 PHP
PHP 7.1中AES加解密方法mcrypt_module_open()的替换方案
2017/10/17 PHP
测试JavaScript字符串处理性能的代码
2009/12/07 Javascript
js中scrollHeight,scrollWidth,scrollLeft,scrolltop等差别介绍
2012/05/16 Javascript
jquery方法+js一般方法+js面向对象方法实现拖拽效果
2012/08/30 Javascript
javascript-简单的日历实现及Date对象语法介绍(附图)
2013/05/30 Javascript
javascript操作Cookie(设置、读取、删除)方法详解
2015/03/18 Javascript
javascript+css3 实现动态按钮菜单特效
2016/02/06 Javascript
js+css实现回到顶部按钮(back to top)
2016/03/02 Javascript
javascript函数自动执行常用方法汇总
2016/03/28 Javascript
Vue.js组件使用开发实例教程
2016/11/01 Javascript
node.js中axios使用心得总结
2017/11/29 Javascript
vue实现键盘输入支付密码功能
2018/08/18 Javascript
js利用递归与promise 按顺序请求数据的方法
2019/08/30 Javascript
解决layui table表单提示数据接口请求异常的问题
2019/09/24 Javascript
js实现适配移动端的拖动效果
2020/01/13 Javascript
Javascript ParentNode和ChildNode接口原理解析
2020/03/16 Javascript
如何在vue中使用百度地图添加自定义覆盖物(水波纹)
2020/11/03 Javascript
下载给定网页上图片的方法
2014/02/18 Python
在Python中使用next()方法操作文件的教程
2015/05/24 Python
Python计时相关操作详解【time,datetime】
2017/05/26 Python
Python实现将数据框数据写入mongodb及mysql数据库的方法
2018/04/02 Python
Python2和Python3的共存和切换使用
2019/04/12 Python
Django admin model 汉化显示文字的实现方法
2019/08/12 Python
python nmap实现端口扫描器教程
2020/05/28 Python
HTML5实现文件断点续传的方法
2017/01/04 HTML / CSS
Html5 canvas实现粒子时钟的示例代码
2018/09/06 HTML / CSS
Juice Beauty官网:有机美容产品,护肤与化妆品
2020/06/13 全球购物
介绍一下sql server的安全性
2014/08/10 面试题
家具促销活动方案
2014/02/16 职场文书
简易版租房协议书范本
2014/10/13 职场文书
党员个人批评与自我批评
2014/10/14 职场文书
公司门卫岗位职责
2015/04/13 职场文书
2015年七七事变78周年纪念活动方案
2015/05/06 职场文书
python读取mnist数据集方法案例详解
2021/09/04 Python