ElementUI el-checkbox实现全选反选单选


一、概述

先来看一下效果图

需求:

1. 每一种类型,可以全选,反选(一个都不选),单选(仅选一个或者多个)

2. 保存时,至少有一种类型,选择1个或多个。不能都不选,直接提交空表单。

3. 保存时,提交参数都是id,不能出现中文。

初始页面数据如下:

[{
    "groupId": 1,
    "groupName": "运动",
    "checkAll": false,
    "ischeckAll": [],
    "interestList": [{
        "name": "篮球",
        "tasteId": 10
    }, {
        "name": "足球",
        "tasteId": 11
    }, {
        "name": "乒乓球",
        "tasteId": 12
    }]
}, {
    "groupId": 2,
    "groupName": "棋类",
    "checkAll": false,
    "ischeckAll": [],
    "interestList": [{
        "name": "军旗",
        "tasteId": 14
    }, {
        "name": "象棋",
        "tasteId": 15
    }, {
        "name": "五子棋",
        "tasteId": 16
    }]
}]

提交参数格式如下:

{
    "interestList": [{
        "groupId": 1,
        "itemList": []
    }, {
        "groupId": 2,
        "itemList": [14]
    }]
}

注意:itemList是具体某一项的id,比如:足球。

二、代码实现

test.vue

<template>
  <div style="width:800px;margin-left: 10px;margin-top: 10px">
    <div>
      <span class="big_title">兴趣爱好span>
    div>
    <div class="div_space">div>
    <div v-for="(parent,index) in groupList" :key="index">
      <div>
        <div class="div_space" v-if="index!=0">div>
        <div class="titles">{{ parent.groupName }}div>
        <div>
          <el-checkbox v-model="parent.checkAll" @change="selectAllFunc(parent.groupId,parent.checkAll)"
                       style="float: left;padding-right: 20px">全选
          el-checkbox>
          <el-checkbox-group v-model="parent.ischeckAll">
            <el-checkbox @change="setCheck(parent.groupId)" v-for="(item,index2) in parent.interestList"
                         :value="item.tasteId" :label="item.tasteId" :key="item.tasteId">{{item.name}}
            el-checkbox>
          el-checkbox-group>
        div>
      div>
    div>
    <div class="div_space">div>
    <div>
      <button class="btn btn-primary" @click="form_validation()">保存button>
      <button class="btn btn-cancel" style="margin-left: 5px;" >取消button>
    div>
  div>
template>
<script>
  export default {
    data() {
      return {
        groupList: [
          {
            groupId: 1,
            groupName: '运动',
            checkAll: false,
            ischeckAll: [],
            interestList: [
              {
                name: '篮球',
                tasteId: 10
              },
              {
                name: '足球',
                tasteId: 11
              },
              {
                name: '乒乓球',
                tasteId: 12
              }
            ],
          },
          {
            groupId: 2,
            groupName: '棋类',
            checkAll: false,
            ischeckAll: [],
            interestList: [
              {
                name: '军旗',
                tasteId: 14
              },
              {
                name: '象棋',
                tasteId: 15
              },
              {
                name: '五子棋',
                tasteId: 16
              }
            ],
          }
        ],
        params: {
          interestList:[]
        },
        // groupList: [],  // 所有电梯列表
      }
    },
    mounted() {
      //
      console.log("初始数据",JSON.stringify(this.groupList))
    },
    methods: {
      // 勾选全选动作
      selectAllFunc(id, checkAll) {
        // console.log("执行selectAllFunc", id, checkAll)
        // 遍历列表
        for (let val of this.groupList) {
          // 判断groupId
          if (val.groupId == id) {
            // 判断全选,如果checkAll为true,则遍历interestList,将tasteId填充到ischeckAll中
            // 否则为为空列表,注意:为空时,表示反选。
            val.ischeckAll = checkAll ? val.interestList.map(item => item.tasteId) : []
            // console.log("ischeckAll", val.ischeckAll)
          }
        }
        // console.log(this.groupList)
      },
      // 设置全选状态
      setCheck(id) {
        // console.log("执行setCheck", id)
        for (let val of this.groupList) {
          if (val.groupId == id) {
            // 判断已经选中的列表是否和选项列表数量一致,如果一致为true,否则为false
            val.checkAll = val.ischeckAll.length == val.interestList.length ? true : false
          }
        }
      },
      // 验证表单
      form_validation() {
        // 设置提交参数列表,遍历groupList,组合新的对象
        this.params.interestList = this.groupList.map(item => {
          return {
            groupId: item.groupId,
            itemList: item.ischeckAll
          }
        })
        // console.log(this.params.interestList)
        // 选择标志位
        let select_flag = false
        // 遍历提交参数列表
        for (let val of this.params.interestList) {
          // 判断列表长度,只要其中一组选择了,标准为true
          if (val.itemList.length > 0) {
            select_flag = true
          }
        }
        // 判断兴趣爱好至少选一个
        if (select_flag == false) {
          this.$message.error("兴趣爱好至少选一个")
          return false
        }
        // return false
        this.submit()
      },
      submit(){
        console.log("提交参数",JSON.stringify(this.params))
      }
    }
  }
script>
<style scoped>
  .big_title {
    width: 172px;
    height: 22px;
    font-size: 16px;
    font-family: PingFangSC-Medium, PingFang SC;
    font-weight: 550;
    color: #333333;
    line-height: 22px;
  }

  .div_space {
    height: 15px;
  }
style>

效果如下:

注意:当选择的选项都选中时,会自动勾选全选,否则不勾选。