vue基于element-ui的三级CheckBox复选框功能的实现代码
程序员文章站
2023-11-16 15:35:28
最近vue项目需要用到三级checkbox复选框,需要实现全选反选不确定三种状态。但是element-ui table只支持多选行,并不能支持三级及以上的多选,下面通过本文...
最近vue项目需要用到三级checkbox复选框,需要实现全选反选不确定三种状态。但是element-ui table只支持多选行,并不能支持三级及以上的多选,下面通过本文给大家讲解实现方法。
效果图预览:
首先是页面布局,当然也可已使用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复选框功能的实现代码,希望对大家有所帮助
下一篇: 博客文章参与SEO排名应该这样做