vue3三级嵌套复选框(element-plus)

一、功能描述

        当选择第一级的复选框时下面所有内容全选和取消全选,当选择第二的复选框时第三级的所有内容全选和取消全选。只要有一个第三级的内容没有选,二级和一级则不能勾上。第三级内容全选上了,第二级复选框就钩上。第二级也是同样的道理。看图好理解:

 

 

二、模拟数据结构(三级嵌套数组结构)

const chooseGroups = ref([
  {
    id: 1,
    title: "一级功能架构",
    ischecked:false,
    secondLevel: [
      {
        id: 2,
        title:"二级功能架构",
        ischecked:false,
        thirdLevel: [
          {
            id:4,
            title:"三级功能1",
            ischecked:true,
          },
          {
            id:5,
            title:"三级功能2",
            ischecked:false,
          },
          {
            id:6,
            title:"三级功能3",
            ischecked:true,
          },
        ]
      },
      {
        id: 3,
        title:"二级功能架构",
        ischecked:false,
        thirdLevel: [
          {
            id:7,
            title:"三级功能1",
            ischecked:true,
          },
          {
            id:8,
            title:"三级功能2",
            ischecked:false,
          },
          {
            id:9,
            title:"三级功能3",
            ischecked:true,
          },
        ]
      },
    ],
  },
  {
    id: 10,
    title: "一级功能架构",
    ischecked:false,
    secondLevel: [
      {
        id: 2,
        title:"二级功能架构",
        ischecked:true,
        thirdLevel: [
          {
            id:4,
            title:"三级功能1",
            ischecked:true,
          },
          {
            id:5,
            title:"三级功能2",
            ischecked:true,
          },
          {
            id:6,
            title:"三级功能3",
            ischecked:true,
          },
        ]
      },
      {
        id: 3,
        title:"二级功能架构",
        ischecked:false,
        thirdLevel: [
          {
            id:7,
            title:"三级功能1",
            ischecked:false,
          },
          {
            id:8,
            title:"三级功能2",
            ischecked:false,
          },
          {
            id:9,
            title:"三级功能3",
            ischecked:false,
          },
        ]
      },
    ],
  },
]);

三、基本思路

 1.全选和取消全选

当勾上一级的时候,遍历下面的数组,把二级和三级数组里面的选中值改为true,取消勾上时,把二级和三级数组里面的选中值改为false。当然,把对应的索引也传过来给处理方法,用于标识是哪一个数组里面的,对应上。

当勾上二级的时候,遍历下面的数组,把三级数组里面的选中值改为true,取消勾上时,把三级数组里面的选中值改为false。当然,把对应的索引也传过来给处理方法,用于标识是哪一个数组里面的,对应上。

2.判断是否为全选状态

当三级全勾上的时候,将二级组里面的选中值改为true,顺便判断一下这时候所有二级是不是都选上了,好根据结果看看要不要更新一级的值。如果二级也全部刚好都选上了,则把一级的选中值改为true。当然,把对应的索引也传过来给处理方法,用于标识是哪一个数组里面的,对应上。

四、完整代码

<template>
  <div class="container">
    <!-- 权限配置 -->
    <Commonhead :title="title"></Commonhead>
    <div class="main">
      <div class="title">
        正在配置角色权限:
        <p class="title-value">巡检员</p>
      </div>

      <div class="choose-con">
        <div class="choose-item">
          <!-- 一级 -->
          <div class="choose-item-1" v-for="(item1, index1) in chooseGroups" :key="item1.id">
            <el-checkbox v-model="item1.ischecked" :label="item1.title" size="large" class="one" @change="(val)=>LevelOneSelectAll(val,index1)"/>
            <!-- 二级 -->
            <div class="choose-item-2" v-for="(item2, index2) in item1.secondLevel" :key="item2.id">
              <el-checkbox v-model="item2.ischecked" :label="item2.title" size="large" class="two" @change="(val)=>LevelTwoSelectAll(val,index1,index2)"/>
              <!-- 三级 -->
              <div class="third">
                <div class="choose-item-3" v-for="(item3) in item2.thirdLevel" :key="item3.id">
                <el-checkbox v-model="item3.ischecked" :label="item3.title" size="large" 
                  @change="LevelThreeSelectAll(index1,index2)"/>
              </div>
              </div>
            </div>
          </div>
        </div>
      </div>
      <div class="submit-btn" @click="submit">提交</div>
    </div>
  </div>
</template>

<script setup>
import Commonhead from "../src/components/Commonhead.vue";
const title = ref("角色管理 > 权限配置");

const chooseGroups = ref([
  {
    id: 1,
    title: "一级功能架构",
    ischecked:false,
    secondLevel: [
      {
        id: 2,
        title:"二级功能架构",
        ischecked:false,
        thirdLevel: [
          {
            id:4,
            title:"三级功能1",
            ischecked:true,
          },
          {
            id:5,
            title:"三级功能2",
            ischecked:false,
          },
          {
            id:6,
            title:"三级功能3",
            ischecked:true,
          },
        ]
      },
      {
        id: 3,
        title:"二级功能架构",
        ischecked:false,
        thirdLevel: [
          {
            id:7,
            title:"三级功能1",
            ischecked:true,
          },
          {
            id:8,
            title:"三级功能2",
            ischecked:false,
          },
          {
            id:9,
            title:"三级功能3",
            ischecked:true,
          },
        ]
      },
    ],
  },
  {
    id: 10,
    title: "一级功能架构",
    ischecked:false,
    secondLevel: [
      {
        id: 2,
        title:"二级功能架构",
        ischecked:true,
        thirdLevel: [
          {
            id:4,
            title:"三级功能1",
            ischecked:true,
          },
          {
            id:5,
            title:"三级功能2",
            ischecked:true,
          },
          {
            id:6,
            title:"三级功能3",
            ischecked:true,
          },
        ]
      },
      {
        id: 3,
        title:"二级功能架构",
        ischecked:false,
        thirdLevel: [
          {
            id:7,
            title:"三级功能1",
            ischecked:false,
          },
          {
            id:8,
            title:"三级功能2",
            ischecked:false,
          },
          {
            id:9,
            title:"三级功能3",
            ischecked:false,
          },
        ]
      },
    ],
  },
]);
// 一级全选和取消全选
const LevelOneSelectAll = (ischeck,index1) => {
  // ischeck是复选框选中之后的新值(true,false)
  // 如果当前一级勾选上了
  if (ischeck) {
    // 先更新一级的勾选状态
    chooseGroups.value[index1].ischecked = true;
    // 然后遍历二级数组更新所有勾选状态为true
    chooseGroups.value[index1].secondLevel.forEach(item2 => {
      item2.ischecked = true;
      // 然后遍历三级数组更新所有勾选状态为true
      item2.thirdLevel.forEach(item3 => {
        item3.ischecked = true;
      });
    });
  } else {
    // 先更新一级的勾选状态
    chooseGroups.value[index1].ischecked = false;
    // 然后遍历二级数组更新所有勾选状态为fasle
    chooseGroups.value[index1].secondLevel.forEach(item2 => {
      item2.ischecked = false;
      // 然后遍历三级数组更新所有勾选状态为false
      item2.thirdLevel.forEach(item3 => {
        item3.ischecked = false;
      });
    });
  }
};
// 二级全选和取消全选
const LevelTwoSelectAll = (ischeck,index1,index2) => {
  checkLevelTwoAllSelected(index1);
  // 如果当前二级勾选上了
  if (ischeck) {
    // 先更新二级的勾选状态
    chooseGroups.value[index1].secondLevel[index2].ischecked = true;
    // 然后遍历二级数组更新所有勾选状态为true
    chooseGroups.value[index1].secondLevel[index2].thirdLevel.forEach(item3 => {
      // 然后遍历三级数组更新所有勾选状态为true
        item3.ischecked = true;
    });
  } else {
    // 先更新二级的勾选状态
    chooseGroups.value[index1].secondLevel[index2].ischecked = false;
    // 然后遍历二级数组更新所有勾选状态为fasle
    chooseGroups.value[index1].secondLevel[index2].thirdLevel.forEach(item3 => {
      // 然后遍历三级数组更新所有勾选状态为fasle
        item3.ischecked = false;
    });
  }
};
// 三级全选判断
const LevelThreeSelectAll = (index1,index2)=>{
  // 假设三级全选上了
  let isAllSelcted = true;
  // 遍历看看有没有都选上了
    for (let i = 0; i < chooseGroups.value[index1].secondLevel[index2].thirdLevel.length; i++) {
      // 如果chooseGroups.value[index1].secondLevel[index2].thirdLevel[i].ischecked这个为false就是有没选上的
      if(!chooseGroups.value[index1].secondLevel[index2].thirdLevel[i].ischecked){
        // 把全选的值改为false
        isAllSelcted = false;
        break;
      }
    }
    // 做完遍历之后,再来看看最终的假设值isAllSelcted
    // 如果全选上了,就把二级的改为true
    if(isAllSelcted){
      chooseGroups.value[index1].secondLevel[index2].ischecked = true;
    }else{
      // 如果有 没有选上的,就把二级的改为false
      chooseGroups.value[index1].secondLevel[index2].ischecked = false;
    }
    // 最后再去检查一下所有二级是不是都选上了,好根据结果看看要不要更新一级的值
    checkLevelTwoAllSelected(index1);
}
// 检查所有二级是否选上
const checkLevelTwoAllSelected = (index1) =>{
  // 假设二级全选上了
  let isAllSelcted = true;
  // 遍历看看有没有都选上了
    for (let i = 0; i < chooseGroups.value[index1].secondLevel.length; i++) {
      if(!chooseGroups.value[index1].secondLevel[i].ischecked){
        isAllSelcted = false;
        break;
      }
    }
    // 做完遍历之后,再来看看最终的假设值isAllSelcted
    // 如果全选上了,就把一级的改为true
    if(isAllSelcted){
      chooseGroups.value[index1].ischecked = true;
    }else{
      chooseGroups.value[index1].ischecked = false;
    }
}
// 提交按钮
const submit = () => {
  console.log(chooseGroups.value);
}
</script>

<style scoped>
.container {
  padding: 20px;
}
.main {
  width: 800px;
  margin: 0 auto;
}
.title-value {
  color: #f5b90f;
  font-weight: 600;
  margin-left: 10px;
}
.title {
  display: flex;
  align-items: center;
}
.choose-item-1 {
  margin-left: 10px;
  margin-bottom: 10px;
}
.choose-item-2 {
  margin-left: 20px;
  margin-top: 10px;
}
.choose-item-3 {
  margin-top: 10px;
  margin-left: 30px;
}
.one::before {
  position: absolute;
  content: '';
  width: 800px;
  height: 40px;
  left: -10px;
  top: 0;
  z-index: -1;
  background-color: #c5c3bb;
}
.two::before {
  position: absolute;
  content: '';
  width: 780px;
  height: 40px;
  left: -10px;
  top: 0;
  z-index: -1;
  background-color: #f6f6f6;
}
.third {
  display: flex;
  align-items: center;
}
.submit-btn {
  width: 100px;
  height: 30px;
  line-height: 30px;
  text-align: center;
  background-color: #f5b90f;
  color: #fff;
  font-size: 13px;
  border-radius: 5px;
  margin: 40px auto;
}
</style>

代码里面有详细的解释,就不必多说了。仔细看一下,注意一下就好了!欢迎交流! 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/429576.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

使用GitHub API 查询开源项目信息

一、GitHub API介绍 GitHub API 是一组 RESTful API 接口&#xff0c;用于与 GitHub 平台进行交互。通过使用 GitHub API&#xff0c;开发人员可以访问和操作 GitHub 平台上的各种资源&#xff0c;如仓库、提交记录、问题等。 GitHub API 提供了多种功能和端点&#xff0c;以…

HTTP有什么缺陷,HTTPS是怎么解决的

缺陷 HTTP是明文的&#xff0c;谁都能看得懂&#xff0c;HTTPS是加了TLS/SSL加密的&#xff0c;这样就不容易被拦截和攻击了。 SSL是TLS的前身&#xff0c;他俩都是加密安全协议。前者大部分浏览器都不支持了&#xff0c;后者现在用的多。 对称加密 通信双方握有加密解密算法…

零基础如何快速入门伦敦金交易

伦敦金交易是金融市场中备受关注的一种投资方式。对于想要学习如何炒伦敦金并快速开始交易的人来说&#xff0c;本文将为您提供一份全面而详细的指南。无论您是初学者还是有经验的交易者&#xff0c;本文都将帮助您了解伦敦金交易的基本知识&#xff0c;并提供一些实用的技巧和…

如何在 Windows 11/10 中合并分区而不丢失数据

在本文中&#xff0c;我们将了解如何在 Window 11/10 中合并分区而不丢失个人数据。每个人都会觉得需要扩大驱动器/分区的容量&#xff0c;但是在计算机中重新安装Windows对他们来说很麻烦。在 Windows PC 中合并分区的方法有很多种。我们将在下面逐步讨论一些工作方法&#xf…

IDEA中Maven无法下载jar包问题解决

在项目中经常会遇到jar包无法下载的问题&#xff0c;可以根据以下几种方法进行排查。 1. 排查网络连接 网络连接失败&#xff0c;会导致远程访问Maven仓库失败&#xff0c;所以应确保网络连接正常。 2. 排查Maven的配置 Maven配置文件&#xff08;settings.xml&#xff09;…

计算机网络-物理层-传输媒体

传输媒体的分类 导向型-同轴电缆 导向型-双绞线 导向型-光纤 非导向型

某品零食交易平台设计与实现|基于springboot+ Mysql+Java的某品交易平台设计与实现(源码+数据库+文档+PPT)

目录 基于springboot MysqlJava的某品交易平台设计与实现 摘 要 系统详细设计 数据库设计 论文参考 源码获取 文末获取源码联系 基于springboot MysqlJava的某品交易平台设计与实现 摘 要 随着科学技术的飞速发展&#xff0c;社会的方方面面、各行各业都在努力与现代的…

嵌入式驱动学习第二周——Linux内核打印

前言 这篇博客来聊一聊Linux内核打印。 嵌入式驱动学习专栏将详细记录博主学习驱动的详细过程&#xff0c;未来预计四个月将高强度更新本专栏&#xff0c;喜欢的可以关注本博主并订阅本专栏&#xff0c;一起讨论一起学习。现在关注就是老粉啦&#xff01; 目录 前言1. dmesg指令…

RabbitMQ(三):AMQP协议

目录 1 AMQP协议1.1 AMQP协议介绍1、AMQP是什么2、消息代理中间件的职责 1.2 AMQP 0-9-1模型1、AMQP的工作过程2、交换器和交换器类型3、队列队列属性队列名称队列持久化 1.3 几个概念1、绑定2、消费者3、消息确认4、预取消息5、消息属性和有效载荷&#xff08;消息主体&#x…

latex编译生成的pdf文件,图片出现浅色的线

目录 问题描述&#xff1a; 解决办法&#xff1a; 问题描述&#xff1a; 在overleaf中&#xff0c;导入图片&#xff0c;编译之后&#xff0c;不知道为什么会出现一条浅色的线&#xff0c;很影响视觉效果&#xff08;ps:在浏览器中看不到这条线&#xff0c;但是在pdf阅读器中…

window路径特殊字符解决

官方定义命名规范 https://learn.microsoft.com/zh-cn/windows/win32/fileio/naming-a-file 重点 1.目录规范 特殊字符以空格 与点.开头结尾 2.文件规范 特殊字符以空格 与点.开头结尾NUL、COM等文件 解决方案 字符标点符号实际上在字符集定义中有一个很有趣的现象&…

两天学会微服务网关Gateway-Gateway HelloWorld快速入门

锋哥原创的微服务网关Gateway视频教程&#xff1a; Gateway微服务网关视频教程&#xff08;无废话版&#xff09;_哔哩哔哩_bilibiliGateway微服务网关视频教程&#xff08;无废话版&#xff09;共计17条视频&#xff0c;包括&#xff1a;1_Gateway简介、2_Gateway工作原理、3…

【C语言基础】:深入理解指针(二)

文章目录 深入理解指针一、指针运算1. 指针 - 整数2. 指针 - 指针3. 指针的关系运算 二、野指针1. 野指针成因2. 如何避免野指针 三、assert断言四、指针的使用和传址调用4.1 strlen的模拟实现4.2 传值调用和传址调用 五、指针与数组5.1 数组名的理解5.2 指针访问数组5.3 一维数…

解放人力,提升品质:码垛输送机的工业应用与价值

在现代工业生产中&#xff0c;码垛输送机已成为许多企业自动化生产线上的关键设备。它不仅可以提高生产效率&#xff0c;降低人力成本&#xff0c;还能确保产品质量&#xff0c;并为企业带来许多其他方面的实际好处。 1. 提高生产效率&#xff1a; 快速码垛&#xff1a;码垛输…

1905_ARMv7-M的堆栈寄存器

1905_ARMv7-M的堆栈寄存器 全部学习汇总&#xff1a; g_arm_cores: ARM内核的学习笔记 (gitee.com) ARMv7-M实现了2种堆栈&#xff0c;分别是MSP和PSP。复位的时候默认是MSP&#xff0c;而当前是哪种可以通过CONTROL.SPSEL寄存器的bit来查看。 SP寄存器的最低2bit&#xff0c;S…

实验01-STP+链路聚合+VRRP实验

1.实验拓扑 2 实验需求 根据拓扑图配置IP地址。交换机之间通过STP防环为了防止SW2-SW3之间聚合的高效链路被STP 阻塞&#xff0c;请配置SW2 为网络中的主根&#xff0c;SW3为网络中的备份根桥。通过VRRP实现网关冗余&#xff0c;网关在SW2和SW3上&#xff0c;其中VLAN10的网关…

【go从入门到精通】go基本类型和运算符用法

大家好&#xff0c;这是我给大家准备的新的一期专栏&#xff0c;专门讲golang&#xff0c;从入门到精通各种框架和中间件&#xff0c;工具类库&#xff0c;希望对go有兴趣的同学可以订阅此专栏。 --------------------------------------------------------------------------…

Full-RNS CKKS

参考文献&#xff1a; [HS13] Halevi S, Shoup V. Design and implementation of a homomorphic-encryption library[J]. IBM Research (Manuscript), 2013, 6(12-15): 8-36.[BEHZ16] Bajard J C, Eynard J, Hasan M A, et al. A full RNS variant of FV like somewhat homomo…

【Java EE初阶二十九】Linux 系统的学习

当前写的博客系统程序,只是部署在咱们自己的电脑上,其他用户是无法直接访问的.由于 NAT 机制的存在,导致了IP 地址就被分成了 内网 IP 和 外网 IP. 云服务器,包括公司中使用专用服务器,一般都是 Linux 系统&#xff0c;这个系统的使用和 Windows 差异很大.(通过命令行来操作的系…

汽车零部件制造中的信息抽取技术:提升效率与质量的关键

一、引言 在汽车制造业中&#xff0c;零部件的生产是整个制造流程的关键一环。这些零部件&#xff0c;包括但不限于制动系统、转向系统和传动系统&#xff0c;是确保汽车安全、可靠运行的基础。为了满足现代汽车工业对效率和质量的严格要求&#xff0c;制造商们纷纷投入到高度…