vue+elementUI 添加多个可以全选的多选框
elementUI-checkbox官网:https://element.eleme.cn/#/zh-CN/component/checkbox
一、要做上面这种效果,首先要了解全选框中indeterminate 状态和v-model的变量的关系 参考 -Dayer-:
<el-checkbox :indeterminate="isIndeterminate" v-model="selected" @change="handleCheckAllChange($event, 'hd')">华东</el-checkbox>对于indeterminate和v-model绑定的isIndeterminate和selected的值分别为:
isIndeterminateselected描述结果true | true或false | 样式为 -,不确定状态 |
false | true | 样式为 √,被选中状态 |
false | false | 不勾,没有被选中 |
总结:isIndeterminate 在全选和未被全选状态下都是 false,其他状态下是 true; selected 只有全选状态下是 true,其他都是 false(或者你也可以设置成:只要子级被选中,那么selected=true,子级一个都没有被选,selected=false。我在这里用的是第一个)。
二、具体案例参考:https://www.jb51.net/article/148826.htm
1. 做这种有多个全选复选框的,最好是让后台帮忙加一下字段,不然就跟官网上的案例一样,每个一级菜单下添加一个数组变量用来存放数据。
字段isIndeterminate(全选复选框显示状态),selected(CheckBox选中状态,是否被选中)。
在一级菜单下添加:isIndeterminate、 selected,二级菜单下每条数据只要添加 selected 就行了。
2. 思路
注释部分有很多是废话,方便理解,开发时可以删除,留下自己认为比较重要的注释就可以啦~
3. 具体代码
(1)模板部分代码:
(2)全选复选框,和单个选择复选框的方法:
// 是否全选 allCheckboxGroup(e,preList,sonList){console.log(e , preList, sonList)if( e ){ //这里的e就是一级菜单的selectedif( sonList ){//不论子菜单是否被选中,只要一级菜单被选中,让该子菜单的selected都=true;for(let i = 0 ;i < sonList.length; i++){sonList[i].selected = true;}//因为在选中部分子菜单的情况下,再点击全选按钮。这种情况也能使一级菜单的selected=true,//此时一级菜单的isIndeterminate=true(且这种情况只有 子菜单存在 才能发生)。//但是只要被全选,一级菜单的isIndeterminate就要=false。preList.isIndeterminate = false; }} else {//因为让一级菜单的selected=false只有在全部都被选中的情况下发生,所以一级菜单的isIndetermainate是一直=false的if( sonList ) {for(let i = 0 ;i < sonList.length; i++){sonList[i].selected = false;}}}//要知道,让一级菜单的isIndeterminate=true,都是必须要操作子菜单才能做到的 },//单个选择 checkOneBox(preList,sonList){//tickCount选了的总量,unTickCount没选数量 这里的 e就是当前复选框的selected值var tickCount = 0, unTickCount = 0, len = sonList.lengthfor(let i=0; i<len; i++){if( sonList[i].selected == true) tickCount++;if( sonList[i].selected == false) unTickCount++;}if(tickCount == len){ //选中数量=子级总数,全选preList.selected = true;preList.isIndeterminate = false;} else if ( unTickCount == len ){ //未选中数量=子级总数,未全选preList.selected = false;preList.isIndeterminate = false;} else { //其他情况是不确定状态preList.selected = false;preList.isIndeterminate = true;} },(3) 因为我这是在弹框中写的,这里将打开弹框和关闭弹框时的操作贴一下:
我这边的需求是,只要选了子菜单,那么该子菜单的父级菜单(一级菜单)也要被添加。
打开elementUI弹框这一部分可以看我另一篇博客 elementUI清空弹框中的表单数据
(4)提交数据
//提交查询、添加、修改 onSubmit(formName) {this.$refs.addForm.validate(valid => {if (valid) {this.isDialog = false;//将已经选中的复选框的值处理一下,放到arr中let arr = [];for(let i =0 ;i<this.selectMenuArr.length; i++){if(this.selectMenuArr[i].selected){ //selected=true.有子说明全选,无子说明只有一个菜单且被选中if(this.selectMenuArr[i].list){for(let j=0; j<this.selectMenuArr[i].list.length; j++){arr.push(this.selectMenuArr[i].list[j].menuId);}}arr.push(this.selectMenuArr[i].menuId);} else {if(this.selectMenuArr[i].isIndeterminate){//isIndeterminate=true.说明一定有子,且选了一部分for(let j=0; j<this.selectMenuArr[i].list.length; j++){if(this.selectMenuArr[i].list[j].selected){arr.push(this.selectMenuArr[i].list[j].menuId);}}arr.push(this.selectMenuArr[i].menuId);}}}//添加 if (formName === 'addForm') { //因为我这边后台要求传字符串,且修改时,要角色菜单为发生变化就传 null。this.addForm.menuIds = arr.length == 0 ? "" : arr.sort(function(a,b){return a-b;}).join();//------添加接口-------}//修改else if (formName === 'updateForm') {//判断角色是否修改,没修改传 null,修改了传字符 this.addForm.menuIds = this.menuIdsArr.sort(function(a,b){return a-b;}).join() == arr.sort(function(a,b){return a-b;}).join() ? null : arr.sort(function(a,b){return a-b;}).join();//------修改接口-------}} else {return false;}}); },(5)获取复选框的动态数据:
selectRoleMenus(){this.$axios.post("接口").then(res => {this.storageArr = res.list;//因为在选择复选框时会操作到selectMenuArr ,而我们打开添加弹框时需要初始数据,所以将初始数据保留一份。this.selectMenuArr = res.list; }) } //记得在created中使用方法。补充:
1. 比较两个数组是否相等 是否拥有相同元素:
<script type="text/javascript">alert([1,2,3].toString()== [3,2,1].toString());alert([1,2,3].sort(function(a,b){return a-b;}).toString()== [3,2,1].sort(function(a,b){return a-b;}).toString()); </script>2. 从接口获取的数据 同时赋值给两个变量,改变其中一个变量时,另一个变量的值也会改变:
引用数据类型赋值时只是给变量保存一个指针,指向存储在堆中的对象,所以两个变量实际上是指向的同一个地方。
解决方法是进行深度复制,因为在拷贝字符串时会开辟新的存储地址,这样就切断了该对象的指针与其指向地址的联系。( 听说如果拷贝对象包含正则表达式,函数,或者undefined等值时,深度烤贝会失效 )
3. 根据某个特定的值删除数组中的指定元素:
var arr = [2,3,5,9,54,21]; arr.splice( arr.indexOf(5), 1 ); //删除数组中的5 创作挑战赛新人创作奖励来咯,坚持创作打卡瓜分现金大奖总结
以上是生活随笔为你收集整理的vue+elementUI 添加多个可以全选的多选框的全部内容,希望文章能够帮你解决所遇到的问题。
- 上一篇: vue+element 封装公共js代码
- 下一篇: 手把手教你用 elementUI 实现导