vue2 el-checkbox 实现分组全选 / 反选 / 半选
作者:Mr.Cactus
- 2022 年 8 月 28 日 江苏
本文字数:2790 字
阅读完需:约 9 分钟
前言
本文以权限的分组全选/反选/半选为例进行展开,实际上,该方法可以用于任何有分组全选需求的场所,当然分组全选/反选/半选的实现也并不只有这一种方法,该文章仅供参考。
0.0 先放上效果图
0.1 选中的值
具体实现方法:
一、准备权限文件
首先准备好权限列表,我一般喜欢放在一个单独的文件中并给这个文件命名为 authority.js,这样看起来更加直观,而且将来对现有权限条目进行增删时也比较好处理,别忘了要导出该权限对象。
export const authorityList = [
{
name: '基础信息',
type: 'base',
list: ['产品信息', '客户信息', '产线信息']
},
{
name: '仓储管理',
type: 'stock',
list: ['生产管理', '出库清单', '退货清单']
},
{
name: '查询统计',
type: 'search',
list: ['生产库存', '出库统计', '数码查询']
},
{
name: '促销管理',
type: 'promotion',
list: ['专卖店管理', '奖品管理', '活动管理', '中奖记录', '扫码记录', '积分管理', '会员信息']
},
{
name: '系统设置',
type: 'set',
list: ['用户管理', '数据对接', '参数设置']
}
]
复制代码
二、在需要用到的地方引入
vue 2 中,导入的对象无法直接在<template>中使用,所以需要定义一个变量来接收该权限对象,同时,定义一些需要使用的变量与方法,详情如代码所示:
<script>
import {authorityList} from '@/utils/authority.js'
export default {
name: 'user',
data() {
return {
authorityList: authorityList, // 用该变量进行接收引入的权限对象
checkedList: {
base: [],
stock: [],
search: [],
promotion: [],
set: []
}, // 选中的权限对象,用不同的数组存放不同类型的权限
indeterminateObj: {
base: false,
stock: false,
search: false,
promotion: false,
set: false
}, // 用来控制对应权限组名称前复选框半选时的显示样式 true:显示为半选样式,false:不显示
checkAllObj: {
base: false,
stock: false,
search: false,
promotion: false,
set: false
} // 对应权限组名称前复选框的全选/反选时的样式的变量 true: 显示为全选样式,false:不显示
}
},
methods: {
// 处理全选/反选事件
handleCheckAll(e1, e2) {
// e1: 权限类型 base、stock、search、promotion、set
// e2: 选择的状态 true: 选中, false: 取消
let index = this.authorityList.findIndex(ele => ele.type == e1) // 找到选中的权限在权限对象中的位置
if(e2) {
// 如果是全选
this.checkedList[e1].push(...this.authorityList[index].list) // 将引入的权限对象中对应的权限push入对应的选中对象中
this.checkAllObj[e1] = true // 将对应权限组名称前的复选框显示为勾选
} else {
// 如果是取消全选
this.checkedList[e1].splice(0, this.checkedList[e1].length) // 清空已选择的权限
this.checkAllObj[e1] = false // 取消对应权限组名称前的勾选状态
}
this.indeterminateObj[e1] = false // 全选/反选后,都需要将半选状态清除
},
// 处理半选事件
handleCheck(e1) {
// e1: 权限type: base、stock、search、promotion、set
let index = this.authorityList.findIndex(ele => ele.type == e1)
// 显示/取消点击的权限对应的权限组名称前的复选框的半选样式
this.indeterminateObj[e1] = this.checkedList[e1].length > 0 && this.checkedList[e1].length < this.authorityList[index].list.length
// 如果一个一个点击,全部选中/取消了对应权限组内的所有权限
if(this.checkedList[e1].length == this.authorityList[index].list.length) {
// 取消显示该权限组名称前复选框的半选状态
this.indeterminateObj[e1] = false
// 改为全选样式
this.checkAllObj[e1] = true
} else {
// 没有通过一个个点击选择对应权限组的全部权限即半选状态,就不显示全选的样式
this.checkAllObj[e1] = false
}
},
}
}
</script>
复制代码
三、html 内容:
<table
class="auth-table"
cellspacing="0"
cellpadding="0"
border-collapse="collapse"
width="100%"
>
<tr v-for="outerItem in authorityList" :key="outerItem.type">
<td class="first-td">
<el-checkbox
@change="handleCheckAll(outerItem.type, $event)"
:indeterminate="indeterminateObj[outerItem.type]"
v-model="checkAllObj[outerItem.type]"
>{{outerItem.name}}</el-checkbox>
</td>
<td class="second-td">
<el-checkbox-group v-model="checkedList[outerItem.type]" @change="handleCheck(outerItem.type)">
<el-checkbox v-for="innerItem in outerItem.list" :key="innerItem" :label="innerItem" >{{innerItem}}</el-checkbox>
</el-checkbox-group>
</td>
</tr>
</table>
复制代码
尾声
自此,vue 2 中的分组全选功能已经完成,当然并不限于权限的全选,也可以是商品等各种有全选功能需求的场所,实现方式也并不只有这一种,此文章仅提供一个参考。
附上用到的样式(less)
.auth-table {
width: 100%;
border: 1px solid #ececec;
border-bottom: none;
border-radius: 4px;
color: #303133;
font-size: 15px;
td {
height: 50px;
border: 1px solid #ececec;
}
.first-td {
width: 160px;
text-align: center;
border-top: none;
border-right: none;
border-left: none;
background: #f8f8f8;
}
.second-td {
padding-left: 15px;
border-top: none;
border-right: none;
}
}
复制代码
注意
element UI 2.13.0 中(其他版本尚不清楚),el-checkbox-group 绑定的用于盛放选中的值的数组中有时候可能会出现重复的值,在使用前最好进行下去重。
// 因为使用选中的值的时候,并不需要对页面进行响应式更新,所以采用了直接赋值的方法
// 如果需要对页面进行响应式更新,把这里的直接赋值操作改为通过数组的响应式方法赋值即可
for(let key in this.checkedList) this.checkedList[key] = [...new Set(this.checkedList[key])]
复制代码
划线
评论
复制
发布于: 刚刚阅读数: 3
版权声明: 本文为 InfoQ 作者【Mr.Cactus】的原创文章。
原文链接:【http://xie.infoq.cn/article/31478f03070fdd042f3366bf0】。文章转载请联系作者。
Mr.Cactus
关注
所思在远道 2020.08.19 加入
一只慢慢进步的小白
评论