当前位置: 首页 > news >正文

vue3中实现el-tree通过ctrl或shift批量选择节点并高亮展示

一、看效果:

按住ctrl键实现单个多选                                按住shift实现区间范围多选                              

                  

二、代码:

        vue页面

<template><el-treeclass="w100%":data="$.treeData"ref="treeTableListRef":props="$.defaultProps"highlight-current:expand-on-click-node="false"key="id":default-expand-all="true"@node-click="(data, node) => $.tableFieldsNodeClick(data, node, treeTableListRef)"><template #default="{ data }"><div style="user-select: none">{{ data.name }}</div></template></el-tree>
</template><script setup lang="ts">
import { useData } from "./hooks/index";
const treeTableListRef = ref();
let { $data: $ } = useData();
onMounted(() => {});
onBeforeMount(() => {window.addEventListener("keydown", handleKeyDown);window.addEventListener("keyup", handleKeyUp);
});
// 按下为true
const handleKeyDown = (event: any) => {// 代表按下的是ctrl键if (event.key == "Control") {$.ctrlKeyPressed = true;}// 代表按下的是shift键if (event.key == "Shift") {$.shiftKeyPressed = true;}
};
// 释放为false
const handleKeyUp = (event: any) => {// 代表按下的是ctrl键if (event.key == "Control") {$.ctrlKeyPressed = false;}// 代表按下的是shift键if (event.key == "Shift") {$.shiftKeyPressed = false;}
};
</script><style scoped lang="scss">
</style>

        引入的hooks文件,index.ts

export function useData() {const $data: any = reactive({ctrlKeyPressed: false,shiftKeyPressed: false,shiftKeyFelid: [],defaultProps: {children: "children",label: "name",},treeData: [{name: '一级1',id: 1,children: [{name: '二级1',id: 2,children: [{name: '三级1',id: 2,}, {name: '三级2',id: 3,}, {name: '三级3',id: 4,}, {name: '三级4',id: 5,}, {name: '三级5',id: 6,}]}, {name: '二级2',id: 3,}, {name: '二级3',id: 4,}, {name: '二级4',id: 5,}, {name: '二级5',id: 6,}]}, {name: '一级2',id: 7,children: [{name: '二级1',id: 8,}, {name: '二级2',id: 9,}, {name: '二级3',id: 10,}, {name: '二级4',id: 11,}, {name: '二级5',id: 12,}]}],selectNodes: []})// 节点选中事件$data.tableFieldsNodeClick = (nodeData: any, node: any, treeTableListRef: any) => {const nodes = treeTableListRef.store._getAllNodes();//所有node节点const ishas = $data.selectNodes.includes(node.id)// 递归遍历节点数组进行ID存放function addSelectId(arr: any) {for (const item of arr) {$data.selectNodes.push(item.id)if (Array.isArray(item.children) && item.children.length) {addSelectId(item.children)}}}// 递归遍历删除节点idfunction delSelectId(arr: any) {for (const item of arr) {const index = $data.selectNodes.findIndex((x: any) => x == item.id);$data.selectNodes.splice(index, 1);if (Array.isArray(item.children) && item.children.length) {delSelectId(item.children);}}}// 按住了ctrl键,可以进行单个多选if ($data.ctrlKeyPressed) {// 如果为true代表当前选中的节点已存在if (ishas) {// 查找当前选中的节点的索引const index = $data.selectNodes.findIndex((x: any) => x == node.id);// 删除父节点$data.selectNodes.splice(index, 1);// 删除子节点if (Array.isArray(node.childNodes) && node.childNodes.length) {deleteSelectId(node.childNodes);}} else {// 否则当前选中的节点不存在,就加入到已选节点数组序列$data.selectNodes.push(node.id)// 防止选中的是父节点,就需要递归将子节点加入if (Array.isArray(node.childNodes) && node.childNodes.length) {addSelectId(node.childNodes);}}node.isCurrent = !node.isCurrent;// 按下了shift键,可以进行范围多选} else if ($data.shiftKeyPressed) {// 先清空$data.selectNodes = []// 将当前节点放入$data.selectNodes.push(node.id)$data.shiftKeyFelid.push(node.id);if ($data.shiftKeyFelid.length > 1) {// 首索引const sIndex = nodes.findIndex((x: any) => x.id == $data.shiftKeyFelid[0])// 尾索引const eIndex = nodes.findIndex((x: any) => x.id == $data.shiftKeyFelid[$data.shiftKeyFelid.length - 1]);// 根据首尾索引,存入中间节点const s = sIndex < eIndex ? sIndex : eIndex //取小值当开头索引const e = sIndex < eIndex ? eIndex : sIndex//取大值当结尾索引for (let i = s; i < e; i++) {// 放入该区间节点id$data.selectNodes.push(nodes[i].id);}}} else {// 否则就是单机选择$data.shiftKeyFelid = [];$data.selectNodes = [];$data.selectNodes = [node.id];}// 下面是对已选中的节点,进行高亮展示// 通过控制elementui中节点上的isCurrent属性// isCurrent为true是高亮,否则取消高亮for (const item of nodes) {if ($data.selectNodes.includes(item.id)) {item.isCurrent = true;} else {item.isCurrent = false;}}};return {$data: $data}
}

三、注意:

        1、重点是要获取当前所选节点数组

        2、通过循环节点数组来更新nodes节点中isCurrent属性,控制高亮

相关文章:

vue3中实现el-tree通过ctrl或shift批量选择节点并高亮展示

一、看效果&#xff1a; 按住ctrl键实现单个多选 按住shift实现区间范围多选 二、代码&#xff1a; vue页面 <template><el-treeclass"w100%":data"$.treeData"ref"treeTab…...

HarmonyOS 振动效果开发指导

Vibrator 开发概述 振动器模块服务最大化开放硬工最新马达器件能力&#xff0c;通过拓展原生马达服务实现振动与交互融合设计&#xff0c;打造细腻精致的一体化振动体验和差异化体验&#xff0c;提升用户交互效率和易用性、提升用户体验、增强品牌竞争力。 运作机制 Vibrato…...

【ACM独立出版、确定的ISBN号】第三届密码学、网络安全和通信技术国际会议(CNSCT 2024)

第三届密码学、网络安全和通信技术国际会议&#xff08;CNSCT 2024&#xff09; 2024 3rd International Conference on Cryptography, Network Security and Communication Technology 随着互联网和网络应用的不断发展&#xff0c;网络安全在计算机科学中的地位越来越重要&…...

Qt12.8

使用手动连接&#xff0c;将登录框中的取消按钮使用qt4版本的连接到自定义的槽函数中&#xff0c;在自定义的槽函数中调用关闭函数 将登录按钮使用qt5版本的连接到自定义的槽函数中&#xff0c;在槽函数中判断ui界面上输入的账号是否为"admin"&#xff0c;密码是否为…...

QT使用SQLite 超详细(增删改查、包括对大量数据快速存储和更新)

QTSQLite 在QT中使用sqlite数据库&#xff0c;有多种使用方法&#xff0c;在这里我只提供几种简单&#xff0c;代码简短的方法&#xff0c;包括一些特殊字符处理。在这里也给大家说明一下&#xff0c;如果你每次要存储的数据量很大&#xff0c;建议使用事务&#xff08;代码中…...

基于Springboot+mybatis+mysql+jsp招聘网站

基于Springbootmybatismysqljsp招聘网站 一、系统介绍二、功能展示四、其他系统实现五、获取源码 一、系统介绍 项目类型&#xff1a;Java EE项目 项目名称&#xff1a;基于SPringBoot的照片网站 项目架构&#xff1a;B/S架构 开发语言&#xff1a;Java语言 前端技术&…...

PHP介绍及安装

一、PHP语言介绍 1. PHP是一种用于创建动态交互性网站的服务器端脚本语言。PHP文件通常包含HTML标签和一些PHP脚本代码,这些PHP代码可以放置在文档的任意位置。 2. PHP文件是什么 PHP文件是一种包含有效的HTML、JavaScript代码和PHP代码的文件。PHP代码在服务器上执行,并将…...

linux C++监听管道文件方式

方式一&#xff08;传统读取文件&#xff0c;一直监听循环读取文件&#xff09; 非阻塞打开文件&#xff0c;用read循环定时读取&#xff0c;性能不好 代码如下&#xff1a; #include <iostream> #include <fstream> #include <functional> #include <…...

【Qt开发流程】之UI风格、预览及QPalette使用

概述 一个优秀的应用程序不仅要有实用的功能&#xff0c;还要有一个漂亮美腻的外观&#xff0c;这样才能使应用程序更加友善、操作性良好&#xff0c;更加符合人体工程学。作为一个跨平台的UI开发框架&#xff0c;Qt提供了强大而且灵活的界面外观设计机制&#xff0c;能够帮助…...

数组实现循环队列(增设队列大小size)

目录 一、前言 1.如何实现循环&#xff1f; 2.如何判断队列为空&#xff1f; 3.如何判断队列为满&#xff1f; 二、循环队列的结构定义 三、循环队列的创建及其初始化 四、入队 五、出队 六、取队头元素 七、取队尾元素 八、循环队列判空 九、循环队列判满 十、循环…...

[BJDCTF2020]EzPHP 许多的特性

这道题可以学到很多东西 静下心来慢慢通过本地知道是干嘛用的就可以学会了 BJDctf2020 Ezphp_[bjdctf2020]ezphp-CSDN博客 这里开始 一部分一部分看 $_SERVER[QUERY_SRING]的漏洞 if($_SERVER) { if (preg_match(/shana|debu|aqua|cute|arg|code|flag|system|exec|passwd|…...

Ubuntu开机出现Welcome to emergency mode解决办法

问题描述 笔记本电脑安装了windows 10和ubuntu 16.04双系统&#xff0c;windows系统关机时按电源键强制关机&#xff0c;再次开机进入Ubuntu系统时无法进入图形界面&#xff0c;出现Welcome to emergency mode。 问题分析 异常关机导致文件系统受损&#xff0c;依据提示使用…...

Android 7.1 默认自拍镜像

Android 7.1 默认自拍镜像 近来收到客户需求反馈需要将相机前摄成像默认为镜像显示&#xff0c;大致思路我们可以在保存数据前将前摄拍的照片转为镜像&#xff0c;保存数据是通过PhotoMode.java文件中的saveData方法实现&#xff0c;具体修改参照如下&#xff1a; 首先添加将图…...

设计模式(二)-创建者模式(5)-建造者模式

一、为何需要建造者模式&#xff08;Builder&#xff09;? 在软件系统中&#xff0c;会存在一个复杂的对象&#xff0c;复杂在于该对象包含了很多不同的功能模块。该对象里的各个部分都是按照一定的算法组合起来的。 为了要使得复杂对象里的各个部分的独立性&#xff0c;以及…...

学习使用三个命令实现在腾讯云服务器TencentOS Server 3.1或者CentOS 8上安装ffmpeg

学习使用三个命令实现在腾讯云服务器TencentOS Server 3.1或者CentOS 8上安装ffmpeg Error: Unable to find a match: ffmpeg添加RPMfusion仓库安装SDL安装ffmpeg执行命令测试 Error: Unable to find a match: ffmpeg 添加RPMfusion仓库 yum install https://download1.rpmfus…...

Java 22种设计模式详解

22种设计模式详解 创建型模式单例模式工厂方法模式抽象工厂模式建造者模式原型模式 结构型模式适配器模式桥接模式组合模式装饰器模式代理模式外观模式享元模式享元模式原理&#xff1a;享元模式角色&#xff1a;示例代码&#xff1a; 行为型模式模板方法模式原理角色示例代码命…...

代码随想录算法训练营第四十八天 _ 动态规划_198.打家劫舍、213.打家劫舍II、337.打家劫舍 III。

学习目标&#xff1a; 动态规划五部曲&#xff1a; ① 确定dp[i]的含义 ② 求递推公式 ③ dp数组如何初始化 ④ 确定遍历顺序 ⑤ 打印递归数组 ---- 调试 引用自代码随想录&#xff01; 60天训练营打卡计划&#xff01; 学习内容&#xff1a; 198.打家劫舍 动态规划五步曲&a…...

记录一下快速上手Springboot登录注册项目

本教程需要安装以下工具&#xff0c;如果不清楚怎么安装的可以看下我的这篇文章 链接: https://blog.csdn.net/qq_30627241/article/details/134804675 管理工具&#xff1a; maven IDE&#xff1a; IDEA 数据库&#xff1a; MySQL 测试工具&#xff1a; Postman 打开IDE…...

【LVGL】STM32F429IGT6(在野火官网的LCD例程上)移植LVGL官方的例程(还没写完,有问题 排查中)

这里写目录标题 前言一、本次实验准备1、硬件2、软件 二、移植LVGL代码1、获取LVGL官方源码2、整理一下&#xff0c;下载后的源码文件3、开始移植 三、移植显示驱动1、enable LVGL2、修改报错部分3、修改lv_config4、修改lv_port_disp.c文件到此步遇到的问题 Undefined symbol …...

Vue学习笔记-Vue3中ref和reactive函数的使用

前言 为了让vue3中的数据变成响应式&#xff0c;需要使用ref,reactive函数 ref函数使用方式 导入ref函数 import {ref} from vue在setup函数中&#xff0c;将需要响应式的数据通过ref函数进行包装&#xff0c;修改响应式数据时&#xff0c;需要通过: ref包装的响应式对象.val…...

开源工具DLSS Swapper:提升游戏帧率的智能版本管理方案

开源工具DLSS Swapper&#xff1a;提升游戏帧率的智能版本管理方案 【免费下载链接】dlss-swapper 项目地址: https://gitcode.com/GitHub_Trending/dl/dlss-swapper 在3A游戏画面日益精美的今天&#xff0c;如何在不牺牲画质的前提下提升帧率成为玩家面临的普遍挑战。…...

5款轻量级效率工具让你的文字识别效率提升300%:Umi-OCR完全指南

5款轻量级效率工具让你的文字识别效率提升300%&#xff1a;Umi-OCR完全指南 【免费下载链接】Umi-OCR OCR software, free and offline. 开源、免费的离线OCR软件。支持截屏/批量导入图片&#xff0c;PDF文档识别&#xff0c;排除水印/页眉页脚&#xff0c;扫描/生成二维码。内…...

Tencent Hunyuan3D-1.0虚幻引擎集成:从生成模型到游戏资产的完整工作流

Tencent Hunyuan3D-1.0虚幻引擎集成&#xff1a;从生成模型到游戏资产的完整工作流 【免费下载链接】Hunyuan3D-1 腾讯开源的Hunyuan3D-1项目&#xff0c;创新提出两阶段3D生成方法&#xff0c;实现快速、高质量的文本到3D和图像到3D转换&#xff0c;融合Hunyuan-DiT模型&#…...

Windows平台Datax部署与初体验:从零到一的数据同步实战

1. Windows平台Datax部署全攻略 第一次在Windows上折腾Datax的经历我还记得很清楚&#xff0c;当时为了同步几个简单的数据表&#xff0c;硬是折腾了大半天。现在回头看&#xff0c;其实只要掌握几个关键步骤&#xff0c;半小时就能搞定。Datax作为阿里开源的数据同步工具&…...

ESP8266 wroom_02 AT固件烧录全攻略:从工具选择到同步下载问题解决

1. ESP8266 wroom_02模块与AT固件基础认知 第一次接触ESP8266 wroom_02模块的朋友可能会被各种专业术语搞晕。简单来说&#xff0c;这个火柴盒大小的模块就是物联网设备的"大脑"&#xff0c;而AT固件则是让它听懂人类指令的"语言系统"。我当年第一次用这个…...

别再只盯着Protobuf了!从DDS到Thrift,聊聊不同IDL在自动驾驶和机器人项目里的真实选型

自动驾驶与机器人系统中的IDL选型实战&#xff1a;从DDS到Thrift的深度解析 在自动驾驶和机器人系统的开发中&#xff0c;接口定义语言(IDL)的选择往往决定了整个通信架构的成败。当激光雷达每秒产生数十万点云数据&#xff0c;当多个传感器需要在毫秒级完成数据融合&#xff…...

DeerFlow部署全攻略:简单几步,打造你的专属AI研究工作站

DeerFlow部署全攻略&#xff1a;简单几步&#xff0c;打造你的专属AI研究工作站 1. 引言&#xff1a;你的个人深度研究助理来了 想象一下&#xff0c;你正在为一个复杂的项目做调研&#xff0c;需要收集资料、分析数据、撰写报告&#xff0c;甚至还要制作演示文稿。传统的方式…...

AI赋能tokenp:借助快马多模型能力生成具备智能风控与建议的钱包原型

最近在尝试用AI辅助开发一个智能化的tokenp钱包原型&#xff0c;发现InsCode(快马)平台的多模型AI能力特别适合快速实现这类需求。今天就来分享下如何用React构建一个带AI风控和建议功能的增强型钱包界面。 项目整体构思 传统钱包应用主要关注资产存储和转账&#xff0c;而结合…...

关于统好 AI可持续发展三大趋势

问&#xff1a;如何理解统好 AI 的可持续发展趋势&#xff1f;答&#xff1a;统好 AI 的可持续发展&#xff0c;核心是技术、业务与运营长期适配&#xff0c;不追求短期迭代&#xff0c;而是围绕企业全生命周期需求构建稳定演进路径。绵阳统好软件有限公司以一体化底座为基础&a…...

Mac 安装 Java JDK 完整教程:一篇文章讲透安装、配置、多版本管理

一、Java JDK 详解1.1 什么是 JDK&#xff1f;JDK&#xff08;Java Development Kit&#xff0c;Java 开发工具包&#xff09;是 Oracle 公司提供的用于 Java 程序开发的完整软件包。它是 Java 开发者不可或缺的核心工具&#xff0c;包含了编写、编译、调试和运行 Java 程序所需…...