写点什么

vue2 el-checkbox 实现分组全选 / 反选 / 半选

作者:Mr.Cactus
  • 2022 年 8 月 28 日
    江苏
  • 本文字数:2790 字

    阅读完需:约 9 分钟

vue2 el-checkbox实现分组全选/反选/半选

前言

本文以权限的分组全选/反选/半选为例进行展开,实际上,该方法可以用于任何有分组全选需求的场所,当然分组全选/反选/半选的实现也并不只有这一种方法,该文章仅供参考。

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
用户头像

Mr.Cactus

关注

所思在远道 2020.08.19 加入

一只慢慢进步的小白

评论

发布
暂无评论
vue2 el-checkbox实现分组全选/反选/半选_Element UI_Mr.Cactus_InfoQ写作社区