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 相关文章推荐
HTML中的setCapture和releaseCapture使用介绍
Mar 21 Javascript
jQuery使用$.get()方法从服务器文件载入数据实例
Mar 25 Javascript
jQuery插件slick实现响应式移动端幻灯片图片切换特效
Apr 12 Javascript
jQuery中的一些小技巧
Jan 18 Javascript
使用bat打开多个cmd窗口执行gulp、node
Feb 17 Javascript
AngularJS实现controller控制器间共享数据的方法示例
Oct 30 Javascript
node错误处理与日志记录的实现
Dec 24 Javascript
p5.js实现动态图形临摹
Oct 23 Javascript
使用webpack搭建pixi.js开发环境
Feb 12 Javascript
vue props default Array或是Object的正确写法说明
Jul 30 Javascript
如何正确解决VuePress本地访问出现资源报错404的问题
Dec 03 Vue.js
微信小程序实现音乐播放页面布局
Dec 11 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
虫族 Zerg 魔法科技
2020/03/14 星际争霸
php下使用无限生命期Session的方法
2007/03/16 PHP
PHP面向对象程序设计高级特性详解(接口,继承,抽象类,析构,克隆等)
2016/12/02 PHP
ThinkPHP 模板substr的截取字符串函数详解
2017/01/09 PHP
PHP5.0~5.6 各版本兼容性cURL文件上传功能实例分析
2018/05/11 PHP
Prototype使用指南之selector.js
2007/01/10 Javascript
javascript高级学习笔记整理
2011/08/14 Javascript
用Js实现的动态增加表格示例自己写的
2013/10/21 Javascript
Javascript毫秒数用法实例
2015/02/05 Javascript
javascript使用avalon绑定实现checkbox全选
2015/05/06 Javascript
vue webpack打包优化操作技巧
2018/02/22 Javascript
Vue中使用的EventBus有生命周期
2018/07/12 Javascript
ztree加载完成后显示勾选节点的实现代码
2018/10/22 Javascript
详解ES7 Decorator 入门解析
2019/02/18 Javascript
python实现图片批量剪切示例
2014/03/25 Python
python中dir函数用法分析
2015/04/17 Python
深入分析python数据挖掘 Json结构分析
2018/04/21 Python
对python 数据处理中的LabelEncoder 和 OneHotEncoder详解
2018/07/11 Python
Python 获取div标签中的文字实例
2018/12/20 Python
PyQt 图解Qt Designer工具的使用方法
2019/08/06 Python
python文字转语音的实例代码分析
2019/11/12 Python
python代码打印100-999之间的回文数示例
2019/11/24 Python
Python中的None与 NULL(即空字符)的区别详解
2020/09/24 Python
html5 video全屏播放/自动播放的实现示例
2020/08/06 HTML / CSS
美国排名第一的在线葡萄酒商店:Wine.com
2016/09/07 全球购物
Monnier Frères美国官网:法国知名奢侈品网站
2016/11/22 全球购物
什么是GWT的Module
2013/01/20 面试题
班主任工作经验材料
2014/02/02 职场文书
装饰活动策划方案
2014/02/11 职场文书
认识深刻的检讨书
2014/02/16 职场文书
廉洁校园实施方案
2014/05/25 职场文书
颂军魂爱军营演讲稿
2014/09/13 职场文书
政府班子四风问题整改措施思想汇报
2014/10/08 职场文书
学生违纪检讨书200字
2014/10/21 职场文书
预备党员群众路线思想汇报2014
2014/10/25 职场文书
springboot @ConfigurationProperties和@PropertySource的区别
2021/06/11 Java/Android