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

news2024/12/26 23:41:31

一、功能描述

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

 

 

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

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>

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

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【暗月安全】2021年渗透测试全套培训视频

参与培训需要遵守国家法律法规&#xff0c;相关知识只做技术研究&#xff0c;请勿用于违法用途&#xff0c;造成任何后果自负与本人无关。 中华人民共和国网络安全法&#xff08;2017 年 6 月 1 日起施行&#xff09; 第二十二条 任何个人和组织不得从事入侵他人网络、干扰他…

折线图实现柱状阴影背景的demo

这个是一个由官网的基础折线图实现的流程&#xff0c;将涉及到的知识点附上个人浅薄的见解&#xff0c;源码在最后&#xff0c;需要的可自取。 折线图 成果展示代码注解参数backgroundColordataZoomlegendtitlexAxisyAxisgridseries 源码 成果展示 官网的基础折线图&#xff…

Android之Handler原理解析与问题分享

一、Handler运行原理剖析 1.关系剖析图 如果把整个Handler交互看做一个工厂&#xff0c;Thread就是动力MessageQueue是履带Looper是转轴Loooper的loop方法就是开关&#xff0c;当调用loop方法时整个工厂开始循环工作&#xff0c;处理来自send和post提交到MessageQueue的消息&a…

Nodejs 第四十五章(redis发布订阅+事务)

发布订阅 发布-订阅是一种消息传递模式&#xff0c;其中消息发布者&#xff08;发布者&#xff09;将消息发送到频道&#xff08;channel&#xff09;&#xff0c;而订阅者&#xff08;订阅者&#xff09;可以订阅一个或多个频道以接收消息。这种模式允许消息的解耦&#xff0…

006-CSS-常见问题汇总

常见问题汇总 1、伪元素与伪类2、偏门但好用的样式3、文字溢出三个点展示4、空白折叠问题5、文字的垂直居中6、 Vue项目中 在父组件中修改子组件样式7、BFC 概念7.1、兄弟元素外边距合并7.2、父子元素外边距塌陷 8、box-sizing8.1、box-sizing: border-box8.2、box-sizing: con…

11. Nginx进阶-HTTPS

简介 基本概述 SSL SSL是安全套接层。 主要用于认证用户和服务器&#xff0c;确保数据发送到正确的客户机和服务器上。 SSL可以加密数据&#xff0c;防止数据中途被窃取。 SSL也可以维护数据的完整性&#xff0c;确保数据在传输过程中不被改变。 HTTPS HTTPS就是基于SSL来…

1.1_2 性能指标——速率、带宽、吞吐量

文章目录 1.1_2 性能指标——速率、带宽、吞吐量&#xff08;一&#xff09;速率&#xff08;二&#xff09;带宽&#xff08;三&#xff09;吞吐量 1.1_2 性能指标——速率、带宽、吞吐量 &#xff08;一&#xff09;速率 速率即数据率或称数据传输率或比特率。 速率就是“快…

【代码】Python3|无GUI环境中使用Seaborn作图的学习路线及代码(阴影折线图)

我有个需求是需要画图&#xff0c;让GPT帮我生成了一下学习计划。 学习路线依照GPT的来的&#xff0c;使用的Prompt工具是https://github.com/JushBJJ/Mr.-Ranedeer-AI-Tutor。 文章目录 PrerequisiteMain Curriculum1.1 Seaborn介绍Seaborn基础保存图形为文件练习 1.2 单变量数…

瑞芯微RK3588 C++部署Yolov8检测和分割模型

最近这一个月在研究国产瑞芯微板子上部署yolov8的检测和分割模型&#xff0c;踩了很多坑&#xff0c;记录一下部署的过程和遇到的一些问题&#xff1a; 1 环境搭建 需要的环境和代码主要包括&#xff1a; &#xff08;1&#xff09;rknn-toolkit2-1.5.2&#xff1a;工具链&am…

uniapp开发android原生插件

一、下载原生开发SDK Android 离线SDK - 正式版 | uni小程序SDK (dcloud.net.cn)、 https://nativesupport.dcloud.net.cn/AppDocs/download/android.html 将开发uniappa原生android的插件解压到ben本地目录&#xff0c;目录结构如下&#xff1a; 接下就可以使用 UniPlugin-Hel…

12 状态优先级

概念 cpu需要执行很多进程&#xff0c;有很多进程排在队列中&#xff0c;每个进程加载后运行一定的时间段&#xff0c;然后切换下一个进程。cpu如何判断进程需不需要加载&#xff0c;什么时候加载&#xff0c;依靠进程的状态和优先级属性来判断&#xff0c;进程调度&#xff0…

Node.js与Webpack笔记(一)

这里使用的16.19.0版本&#xff0c;官网和github没找到&#xff0c;去黑马2023年课程里找 篇幅较大会卡&#xff0c;此篇幅不写Webpack部分&#xff0c;留着下一篇 初识 1.什么是Node.js? Node.js 是一个独立的 JavaScript 运行环境&#xff0c;能独立执行 JS 代码&#xff…

A/D转换

硬件电路模型 模数转换代码 main.c #include <REGX52.H> #include "LCD1602.h" #include "Delay.h" #include "XPT2046.h"unsigned int ADValue; int main(){LCD_Init();LCD_ShowString(1,1,"ADJ NTC RG");while(1){ADValue …

iOS 17.0 UIGraphicsBeginImageContextWithOptions 崩溃处理

在升级到iOS17后你会发现&#xff0c;之前版本运行的很好&#xff0c;这个版本突然会出现一个运行闪退。报错日志为*** Assertion failure in void _UIGraphicsBeginImageContextWithOptions(CGSize, BOOL, CGFloat, BOOL)(), UIGraphics.m:410 跟踪到具体的报错位置如下所示&a…

redis09 集群(cluster)

思维草图 为什么要使用集群 单台redis内存容量的限制单台redis并发写量太大有性能瓶颈 redis集群认识 redis集群是对redis的水平扩容&#xff0c;即启动N个redis节点&#xff0c;将整个数据分布存储在这个N个节点中&#xff0c;每个节点存储总数据的1/N。 如下图&#xff1…

win11部署自己的privateGpt(2024-0304)

什么是privateGpt? privategpt开源项目地址 https://github.com/imartinez/privateGPT/tree/main 官方文档 https://docs.privategpt.dev/overview/welcome/welcome PrivateGPT是一个可投入生产的人工智能项目&#xff0c;利用大型语言模型&#xff08;LLMs&#xff09;的…

Windows安装SSH教程

Windows安装SSH教程 一、SSH1.SSH简介2.SSH功能3.SSH验证3.1 第一种级别&#xff08;基于口令的安全验证&#xff09;3.2 第二种级别&#xff08;基于密匙的安全验证&#xff09; 4.SSH层次4.1 传输层协议 [SSH-TRANS]4.2 用户认证协议 [SSH-USERAUTH]4.3 连接协议 [SSH-CONNEC…

场景问题: VisualVM工具Profiler JDBC不是真实执行的SQL

1. 问题 诡异的问题表象&#xff1a; 前端反馈分页接口的Total字段一直为0 使用Visualvm中的 Profiler 注入到应用后&#xff0c;查看JDBC监控得到了分页接口执行的SQL&#xff0c;复制出来执行是55. 此时还没有注意到 IN 的范围中有一个特别的值 NULL &#x1f928; 2. 排查…

【运维必学】2.零基础搞IT运维之服务器操作系统基础知识储备

微信改版了&#xff0c;现在看到我们全凭缘分&#xff0c;为了不错过【全栈工程师修炼指南】重要内容及福利&#xff0c;大家记得按照上方步骤设置「接收文章推送」哦~ 文章目录&#xff1a; 温馨提示&#xff1a;作者最近开通的知识星球&#xff0c;全栈系列从门到实践教程将会…

QT----写完的程序打包为APK在自己的手机上运行

目录 1、qt安装android组件2、打开qt配置Android 环境3、手机打开开发者模式&#xff0c;打开usb调试&#xff0c;连接电脑4、运行代码 1、qt安装android组件 qtcreater–工具-QTMaintenaceTool-startMaintenaceTool—登陆—添加或修改组件—找到android&#xff0c;安装 若是…