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 在网页上单击鼠标的地方显示层及关闭层
Dec 30 Javascript
js实现获取焦点后光标在字符串后
Sep 17 Javascript
js/jquery判断浏览器类型的方法小结
May 12 Javascript
javascript实现2016新年版日历
Jan 25 Javascript
jQuery ztree实现动态树形多选菜单
Aug 12 Javascript
JS实现的适合做faq或menu滑动效果示例
Nov 17 Javascript
Vue 单文件中的数据传递示例
Mar 21 Javascript
jQuery md5加密插件jQuery.md5.js用法示例
Aug 24 jQuery
微信小程序image图片加载完成监听
Aug 31 Javascript
详解在Vue.js编写更好的v-for循环的6种技巧
Apr 14 Javascript
原生JS实现弹幕效果的简单操作指南
Nov 10 Javascript
如何在 Vue 中使用 JSX
Feb 14 Vue.js
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中截取中文字符串的代码小结
2011/07/17 PHP
php中strlen和mb_strlen用法实例分析
2016/11/12 PHP
yii2 数据库读写分离配置示例
2017/02/10 PHP
不能再简单的无闪刷新验证码原理很简单
2007/11/05 Javascript
JavaScript DOM 学习第七章 表单的扩展
2010/02/19 Javascript
Jquery中对数组的操作代码
2011/08/12 Javascript
jquery三个关闭弹出层的小示例
2013/11/05 Javascript
JavaScript中instanceof与typeof运算符的用法及区别详细解析
2013/11/19 Javascript
使用typeof方法判断undefined类型
2014/09/09 Javascript
学习jQuey中的return false
2015/12/18 Javascript
jQuery实现多级联动下拉列表查询框
2016/01/18 Javascript
JavaScript实现简洁的俄罗斯方块完整实例
2016/03/01 Javascript
JS实现登录页面记住密码和enter键登录方法推荐
2016/05/10 Javascript
深入理解JS函数的参数(arguments)的使用
2016/05/28 Javascript
javascript中获取class的简单实现
2016/07/12 Javascript
AngularJS动态生成div的ID源码解析
2016/08/29 Javascript
jquery实现表单获取短信验证码代码
2017/03/13 Javascript
Bootstrap里的文件分别代表什么意思及其引用方法
2017/05/01 Javascript
Vue Ajax跨域请求实例详解
2017/06/20 Javascript
angular2 ng2 @input和@output理解及示例
2017/10/10 Javascript
JS抛物线动画实例制作
2018/02/24 Javascript
Vue微信项目按需授权登录策略实践思路详解
2018/05/07 Javascript
jQuery实现左右两个列表框的内容相互移动功能示例
2019/01/27 jQuery
利用angular自动编译andriod APK的绕坑经历分享
2019/03/08 Javascript
微信小程序上线发布流程图文详解
2019/05/06 Javascript
vue利用全局导航守卫作登录后跳转到未登录前指定页面的实例代码
2020/05/19 Javascript
[04:29]2014DOTA2国际邀请赛 主赛事第三日TOPPLAY
2014/07/21 DOTA
python通过正则查找微博@(at)用户的方法
2015/03/13 Python
python版百度语音识别功能
2019/07/09 Python
Python collections.deque双边队列原理详解
2020/10/05 Python
Eton丹麦官网:精美的男式衬衫
2020/05/27 全球购物
毕业生幼师求职自荐信
2013/10/01 职场文书
汽车队司机先进事迹材料
2014/02/01 职场文书
员工三分钟演讲稿
2014/08/19 职场文书
升职自我推荐信范文
2015/03/25 职场文书
幼儿园小班教学反思
2016/03/03 职场文书