问题:el-tree点击某节点的复选框由半选状态更改为全选状态以后,点击该节点展开,懒加载出来子节点数据以后,该节点又变为半选状态
具体问题场景:
用户点击父节点复选框将其从半选变为全选(此时子节点尚未加载)。
点击节点展开触发懒加载,加载子节点。
子节点加载后,组件重新计算父节点状态,发现并非所有子节点被选中,因此父节点恢复半选状态
解决方案:
核心思路:手动维护状态一致性
在父节点被手动全选时,即使子节点未加载,仍需保证:
当子节点加载后,自动选中所有子节点
强制更新父节点状态
1. 记录用户手动全选操作
2. 在复选框勾选事件中捕获全选操作
3. 在懒加载子节点后强制选中子节点
4. 清理状态记录(在节点折叠时清理状态记录,避免残留状态影响后续操作)
代码:
<template><el-treeref="tree":data="treeData"lazy:load="loadNode"show-checkboxnode-key="menuId"@check="handleCheck"@node-collapse="handleNodeCollapse"></el-tree>
</template><script>
export default {data() {return {treeData: [],forcedFullCheckedNodes: new Set()};},methods: {async loadNode(node, resolve) {try {// 1. 加载子节点const children = await this.fetchChildren(node.data.menuId);// 2. 如果父节点曾被强制全选,标记子节点为选中if (this.forcedFullCheckedNodes.has(node.data.menuId)) {children.forEach(child => {child.checked = true;child.indeterminate = false;});}resolve(children);// 3. 强制刷新父节点状态this.$nextTick(() => {this.$refs.tree.updateNode(node);});} catch (error) {resolve([]);}},handleCheck(checkedNode) {// 检测是否是手动全选操作const isManualFullCheck = !checkedNode.children && //节点没有子节点(或子节点未加载)checkedNode.indeterminate && //节点之前处于半选状态this.$refs.tree.getCheckedKeys().includes(checkedNode.menuId);//节点当前已全选if (isManualFullCheck) {this.forcedFullCheckedNodes.add(e.menuId);}},handleNodeCollapse(collapsedNode) {// 节点折叠时清除状态记录this.forcedFullCheckedNodes.delete(collapsedNode.menuId);}}
};
</script>
data中定义数据为什么使用forcedFullCheckedNodes: new Set()?
用`Set`来跟踪那些被强制全选的节点,以确保即使子节点加载后,父节点的状态仍保持正确。
Set是JavaScript中的一种数据结构,可以自动保证存储的节点 ID 唯一,避免重复添加相同节点。用forcedFullCheckedNodes来记录那些被用户手动全选的节点ID,这样在加载子节点时,可以检查父节点是否在这个Set中,如果是,就强制其子节点为全选状态,从而保持父节点的全选状态。
为什么选择new Set()而不是其他数据结构,比如数组。Set提供了高效的查找和添加操作,因为Set的has和add方法的时间复杂度接近O(1),而数组的includes和push可能需要遍历,效率较低。尤其是当节点数量较多时,使用Set会更高效。
在节点折叠时清理状态(如从 forcedFullCheckedNodes 中移除节点 ID)的原因主要有以下几点:
1. 避免状态残留干扰后续操作
场景:用户手动全选父节点 → 展开节点加载子节点并强制全选 → 折叠节点(子节点可能被销毁或隐藏)。
风险:若保留父节点的强制全选标记,当用户再次展开时,会重新触发懒加载,此时如果父节点仍在 forcedFullCheckedNodes 中,会重复强制全选子节点,导致以下问题:
若用户之前已手动取消某些子节点,重复强制全选会覆盖用户操作。
若数据已通过其他方式(如后端保存的 checkedKeys)初始化,强制标记会引发状态冲突。
2. 符合用户直觉
用户预期:折叠操作通常意味着“暂时不再关注该节点”,此时清理临时状态更符合直觉。
示例:用户手动全选父节点 → 展开处理子节点 → 折叠节点(视为操作完成)。后续再次展开时,父节点应基于当前实际子节点的选中状态(如从后端获取的最新状态)决定显示全选/选,而非依赖临时标记。
3. 性能优化
内存管理:动态树结构可能有大量节点,及时清理不再需要跟踪的节点,避免 forcedFullCheckedNodes 集合无限膨胀。
响应式开销:在 Vue 中,若使用数组或普通对象存储标记,频繁操作可能触发不必要的响应式更新。而 Set 虽高效,但需手动维护。
4. 与数据持久化配合
正确流程:
用户手动全选父节点 → 立即将所有子孙节点的选中状态提交后端保存。
折叠节点 → 清理 forcedFullCheckedNodes 中的临时标记。
再次展开时 → 通过后端返回的完整 checkedKeys 初始化选中状态,而非依赖内存中的临时标记。
优势:确保父子节点状态始终基于持久化数据,而非临时内存状态,避免数据不一致。
相关文章:
问题:el-tree点击某节点的复选框由半选状态更改为全选状态以后,点击该节点展开,懒加载出来子节点数据以后,该节点又变为半选状态
具体问题场景: 用户点击父节点复选框将其从半选变为全选(此时子节点尚未加载)。 点击节点展开触发懒加载,加载子节点。 子节点加载后,组件重新计算父节点状态,发现并非所有子节点被选中,因此父节…...
【Rust 精进之路之第8篇-工具赋能】深入 Cargo:依赖管理、构建配置与工作空间 (Workspace)
系列: Rust 精进之路:构建可靠、高效软件的底层逻辑 作者: 码觉客 发布日期: 2025-04-20 引言:超越构建,Cargo 是 Rust 生态的引擎 在我们的 Rust 学习之旅初期(第二篇),我们已经与 Cargo 有过初步的接触。我们学会了使用 cargo new 创建项目骨架,用 cargo build 编…...
多模态大语言模型arxiv论文略读(二十六)
Holistic Autonomous Driving Understanding by Bird’s-Eye-View Injected Multi-Modal Large Models ➡️ 论文标题:Holistic Autonomous Driving Understanding by Bird’s-Eye-View Injected Multi-Modal Large Models ➡️ 论文作者:Xinpeng Ding,…...
Java虚拟机(JVM)平台无关?相关?
计算机的概念模型 计算机实际上就是实现了一个图灵机模型。即,输入参数,根据程序计算,输出结果。图灵机模型如图。 Tape是输入数据,Program是针对这些数据进行计算的程序,中间横着的方块表示的是机器的状态。 目前使…...
Ubuntu 安装 Docker 教程(官方推荐方式)
✅ 步骤 1:卸载旧版本(如果有) for pkg in docker.io docker-doc docker-compose docker-compose-v2 podman-docker containerd runc; do sudo apt-get remove $pkg; done---### ✅ 步骤 2:更新 APT 索引并安装依赖项bash sudo a…...
Win10 C盘空间不足清理方法
当Windows 10系统的C盘空间不足时,可以采取以下方法进行清理: 1. 清理临时文件 打开“设置” > “系统” > “存储”。 点击“临时文件”,勾选要删除的临时文件、系统缓存等,然后点击“删除文件”。 2. 使用磁盘清理工具…...
cloudstudio学习笔记之openwebui
代码获取 git clone 参考资料 openwebui官网 https://docs.openwebui.com/getting-started/advanced-topics/development 后端启动 cd backend pip install -r requirements.txt -U sh dev.sh后端启动成功后的界面 在cloudstudio提供的vscode弹出的提示中打开浏览器并在末…...
7.QT-常用控件-QWidget|font|toolTip|focusPolicy|styleSheet(C++)
font API说明font()获取当前widget的字体信息.返回QFont对象.setFont(const QFont& font)设置当前widget的字体信息. 属性说明family字体家族.⽐如"楷体",“宋体”,"微软雅⿊"等.pointSize字体⼤⼩weight字体粗细.以数值⽅式表⽰粗细程度取值范围为[…...
机器学习核心算法全解析:从基础到进阶的 18 大算法模型
在机器学习领域,算法模型是解决实际问题的核心工具。 不同的算法适用于不同的数据场景和任务需求,理解它们的原理与应用是掌握机器学习的关键。 以下将详细解析 18 个核心算法模型,涵盖监督学习、无监督学习、集成学习和深度学习等多个领域…...
线性代数 | 知识点整理 Ref 1
注:本文为 “线性代数 | 知识点整理” 相关文章合辑。 因 csdn 篇幅合并超限分篇连载,本篇为 Ref 1。 略作重排,未整理去重。 图片清晰度限于引文原状。 如有内容异常,请看原文。 线性代数知识汇总 Arrow 于 2016-11-27 16:27:5…...
【深度学习入门_NLP自然语言处理】序章
本部分开始深度学习第二大部分NLP章节学习,找了好多资料,终于明确NLP的学习目标了,介于工作之余学习综合考量,还是决定以视频学习为主后期自主实践为主吧。 分享一个总图,其实在定位的时候很迷茫,单各章节…...
Windows常用维护命令
系统信息查询 systeminfo:查看系统详细信息,如操作系统版本、处理器信息、内存配置等。hostname:显示计算机名称。ver:显示 Windows 版本。 网络诊断 ipconfig:查看 IP 配置,如 IP 地址、子网掩码、网关等。…...
Java 2025:解锁未来5大技术趋势,Kotlin融合AI新篇
各位Java开发者们好!🚀 2025年的Java世界正在经历一场前所未有的技术变革。作为深耕Java领域多年的技术博主,今天我将带大家深入探索Java生态即将迎来的5大技术趋势,特别是Kotlin的深度融合和AI技术的新篇章。准备好了吗ÿ…...
IcePlayer音乐播放器项目分析及学习指南
IcePlayer音乐播放器项目分析及学习指南 项目概述 IcePlayer是一个基于Qt5框架开发的音乐播放器应用程序,使用Visual Studio 2013作为开发环境。该项目实现了音乐播放、歌词显示、专辑图片获取等功能,展现了桌面应用程序开发的核心技术和设计思想。 技…...
蓝桥杯 二进制问题 刷题笔记
8.二进制问题 - 蓝桥云课 存入N的二进制每一位作为基准数组 算出方案数 从高位往低位用dfs枚举每一位是放1还是放0 #include<iostream> #include<vector> #define ll long long using namespace std;ll dp[65][65]; ll num; ll k; vector<ll> vec;ll cal(l…...
20. git diff
基本概述 git diff的作用是:比较代码差异 基本用法 1.工作区 VS 暂存区 git diff [file]2.暂存区 VS 最新提交 git diff --staged [file] # 或 git diff --cached [file]3.工作区 VS 最新提交 git diff HEAD [file]高级用法 1.比较两个提交间的差异 git dif…...
深入剖析 MySQL 中用户授权机制及操作
在数据库管理的庞大体系中,MySQL 作为一款广泛应用的开源关系型数据库管理系统,其用户授权机制对于保障数据安全、确保数据库稳定运行以及满足多样化的业务需求起着举足轻重的作用。当我们遭遇 “Access denied for user icoolkj% to database icoolkj-a…...
mapbox基础,加载视频到地图
👨⚕️ 主页: gis分享者 👨⚕️ 感谢各位大佬 点赞👍 收藏⭐ 留言📝 加关注✅! 👨⚕️ 收录于专栏:mapbox 从入门到精通 文章目录 一、🍀前言1.1 ☘️mapboxgl.Map 地图对象1.2 ☘️mapboxgl.Map style属性1.3 ☘️raster 栅格图层 api二、🍀加载视频到…...
synchronized 与分布式锁
1. synchronized 关键字 定义: synchronized 是 Java 提供的一个内置锁机制,用于控制多线程对共享资源的并发访问。 它可以修饰方法或代码块,确保同一时刻只有一个线程可以执行被 synchronized 修饰的代码。作用范围: 只能用于单…...
获取视频封面
目录 实现方式注意事项代码实现 实现方式 通过 video 元素canvas 元素的方式实现 生成 video 和 canvas 元素当 video 元素资源加载完成时,将 video 元素绘制到 canvas 画布上,然后通过 toBlob 或则 toDataURL 获取到对应的封面图片资源 注意事项 vid…...
RNN - 循环神经网络(实现)
写在前面 在RNN - 循环神经网络(概念介绍)中,介绍了一下 RNN 的相关概念,下面就基于概念对 RNN 进行两种实现。从零开始实现和简洁实现。 从 0 开始实现 首先导入必要的环境,使用 H.G.Wells 的时光机器数据集上训练…...
【FAQ】HarmonyOS SDK 闭源开放能力 —Health Service Kit
1.问题描述: 按照官方文档调用healthStore API申请用户授权;有拉起授权弹窗,但是无回调,检查权限接口也无回调。 解决方案: 1、接口调用前,需先使用init方法进行初始化,没有回调的问题请确认…...
【unity游戏开发入门到精通——UGUI】RectTransform矩形变换组件
注意:考虑到UGUI的内容比较多,我将UGUI的内容分开,并全部整合放在【unity游戏开发——UGUI】专栏里,感兴趣的小伙伴可以前往逐一查看学习。 文章目录 一、RectTransform组件介绍二、RectTransform组件参数1、Pivot 轴心点2、Ancho…...
【Rust 精进之路之第4篇-数据基石·上】标量类型:整数、浮点数、布尔与字符的精妙之处
系列: Rust 精进之路:构建可靠、高效软件的底层逻辑 作者: 码觉客 发布日期: 2025-04-20 引言:构成万物的“原子”——标量类型 在上一篇文章【变量观】中,我们深入探讨了 Rust 如何通过 let、mut、const…...
C语言复习笔记--字符函数和字符串函数(上)
在编程的过程中,我们经常要处理字符和字符串,为了⽅便操作字符和字符串,C语⾔标准库中提供了 ⼀系列库函数,接下来我们就学习⼀下这些函数。 首先来看下字符函数. 字符分类函数 C语⾔中有⼀系列的函数是专⻔做字符分类的…...
Apipost,前端后端测试都在用的接口设计调试工具
大家好,我是袁庭新。给大家介绍一个后端、前端、测试都在用的接口测试工具——Apipost。Apipost主要分为5个大模块,贯穿一个API从设计到测试完成上线的研发全周期。 1.Apipost介绍 Apipost官方地址:https://www.apipost.cn。如下图所示。 A…...
十倍开发效率 - IDEA 插件之RestfulBox - API
提高效率不是为了完成更多的任务,而是有充足的时间摸鱼。 快速体验 RestfulBox - API 是 IDEA 的插件,适合本地测试接口,完全不需要对项目进行任何以来。 接口管理:支持接口扫描、浏览、搜索、跳转、导入和导出。支持接口请求&a…...
2025 年网络安全的挑战与机遇
2024 年是网络安全领域风云变幻的一年。从备受瞩目的勒索软件攻击所带来的影响,到人工智能工具日益商品化,挑战不断增加。 关键基础设施的漏洞变得极为明显,身份盗窃次数也达到了前所未有的程度。然而,在这一片混乱之中ÿ…...
Linux 常用指令用户手册
Linux 常用指令用户手册 适合新手入门 & 日常速查 目录 基础操作文件与目录管理权限与所有权文本处理压缩与解压系统监控网络操作进程管理实用小技巧 1. 基础操作 1.1 查看系统信息 # 查看内核版本 uname -a# 查看系统发行版信息(适用于 Debian/Ubuntu&…...
IP数据报
IP数据报组成 IP数据报(IP Datagram)是网络中传输数据的基本单位。 IP数据报头部 版本(Version) 4bit 告诉我们使用的是哪种IP协议。IPv4版本是“4”,IPv6版本是“6”。 头部长度(IHL,Intern…...
