Vue3计算属性终极实战:可媲美Element Plus Tree组件研发之节点勾选

前面完成了JuanTree组件的节点编辑和保存功能后,我们把精力放到节点勾选功能实现上来。**注意,对于组件的开发者来说,要充分考虑用户的使用场景,组件提供的多个特性同时启用时必须要工作良好。**就拿Tree组件来说,用户完全可以在启用勾选的情况下,同时启用节点增删功能,此时增删不能影响到勾选的一致性。

Tree组件的节点勾选会向下级联所有子孙节点,向上也会影响父节点的全选和半选状态。大部分教程在实现节点勾选,主导的思路就是手动的遍历处理,实现的非常麻烦;本教程的思路让功能实现变得非常简单——使用可写的计算属性即可!

在这里插入图片描述

可以拿官方的例子来复习下可写计算属性的用法:

在这里插入图片描述

然后我们开始上车,进入计算属性的终极实战,Are you ready? Gooooo!

用法示例

示例演示

在这里插入图片描述

启用设置:

在这里插入图片描述

具体实现如下

组件属性和ts类型

JuanTree组件的可选配置上再新增一个可选项,基于它来决定是否启用节点勾选功能。

export interface OptionProps {...checkable?: boolean // 是否启用勾选,默认不启用
}

节点勾选会用三种状态:未选中、选中和半选中,为此定义一个枚举类型:

export enum ECheckedStatus {UNCHECKED,CHECKED,HALF_CHECKED
}

JuanTree的结构化节点类型ITreeNode中新增勾选相关的属性:

// 结构化节点
export interface ITreeNode {...checkedStatus?: WritableComputedRef<ECheckedStatus> // 可写的勾选计算属性checked?: boolean // 是否被选中,实际操作时用到的属性,也会参与到勾选计算属性的计算中
}

计算属性核心逻辑

utils.ts工具中编写结构化节点ITreeNode的初始化绑定函数,关键代码的注释都加了,操作逻辑非常的简单易读:

// 初始化结构化节点
function initTreeNode(treeNode: ITreeNode, props: OptionProps) {// 如果没有启用checkable,则返回if (!props.checkable) return// 获得节点的响应式操作对象const node = ref(treeNode).valueconst childrenName = props.childrenName as 'children'// 绑定节点的勾选计算属性treeNode.checkedStatus = computed({get() {// 如果是叶子节点,返回checked属性值if (!node[childrenName]) {// 叶子节点只有两种状态:选中和未选中return node.checked ? ECheckedStatus.CHECKED : ECheckedStatus.UNCHECKED} else {// 父节点的勾选状态判断逻辑,需要统计子节点的勾选状态let checkedCount = 0,uncheckedCount = 0// 遍历子一代节点列表node[childrenName].forEach((item) => {// 获取子节点的勾选计算属性得到的状态枚举值const status = item.checkedStatus// 统计选中的数量if (status === ECheckedStatus.CHECKED) {checkedCount++} else if (status === ECheckedStatus.UNCHECKED || status == null) {// 统计未选中的数量uncheckedCount++}})const childrenLength = node[childrenName].length// 先进行全选中的判断:存在选中的且选中数量等于子一代节点数量if (checkedCount > 0 && checkedCount === childrenLength) {return ECheckedStatus.CHECKED} else if (uncheckedCount === childrenLength) {// 再进行未选中的判断:没有全选中并且未选中的数量等于子一代节点数量return ECheckedStatus.UNCHECKED} else {// 其余则归结为半选return ECheckedStatus.HALF_CHECKED}}},set(status: ECheckedStatus) {// 基于写入的状态来判断checked值const checked = status === ECheckedStatus.CHECKED// 设置checked属性node.checked = checked// 如果是父节点则进行子一代节点的级联设置,注意设置子节点的checkedStatus计算属性会触发递归调用,达到我们向下递归设置的目的!if (node[childrenName]) {node[childrenName].forEach((child) => {child.checkedStatus = statuschild.checked = checked})}}})
}

初始化扁平化节点的逻辑完善:

在这里插入图片描述

新增一级节点的处理逻辑完善:

在这里插入图片描述

Tree原始数据结构拍平函数的完善:

在这里插入图片描述

tsx模板完善

新增一个点击勾选的事件处理函数

// 节点勾选点击事件处理函数
const checkNode = (node: IFlatTreeNode) => {// 注意,是对原始节点进行操作const oNode = node.originalNodeconst status = oNode.checkedStatus as any// 如果没有选中(可能是半选),执行选中的计算属性写入if (status !== ECheckedStatus.CHECKED) {oNode.checkedStatus = ECheckedStatus.CHECKED as any} else {// 如果选中则执行反选写入计算属性oNode.checkedStatus = ECheckedStatus.UNCHECKED as any}
}

tsx模板中增加选中的图标组件svg-icon,并按照选中状态动态设置icon属性

在这里插入图片描述

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

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

相关文章

大模型训练为何离不开GPU?深度解析与显卡推荐

在人工智能的蓬勃发展中&#xff0c;大模型的训练成为了热门话题。然而&#xff0c;许多人还不清楚为什么训练这些庞大的模型需要GPU&#xff08;图形处理单元&#xff09;。本文将深入探讨GPU在大模型训练中的重要性&#xff0c;并推荐几款适合的显卡。 一、GPU与CPU的区别 …

Java消失的数字

题目要求 数组nums包含从0到n的所有整数&#xff0c;但其中缺了一个。请编写代码找出那个缺失的整数。你有办法在O(n)时间内完成吗&#xff1f; 示例 1&#xff1a; 输入&#xff1a;[3,0,1] 输出&#xff1a;2 示例 2&#xff1a; 输入&#xff1a;[9,6,4,2,3,5,7,0,1] 输出&a…

如何保证前后端交互信息不被篡改。

先说说前后端有哪些认证方式来保证&#xff1a; 基于 session 的认证方式&#xff1a;前端在用户登录成功后&#xff0c;后端会在服务器端生成一个唯一的 session ID&#xff0c;并将该 session ID 返回给前端&#xff0c;在后续的请求中&#xff0c;前端需要带上该 session ID…

【CUDA Runtime】第一个“Hello World“程序

文章目录 前言前提须知CUDA Runtime 简介核心功能优势和应用 使用CudaRuntime进行第一个"Hello world"程序创建CudaRuntime工程选择GPU函数原型参数返回值作用 获取支持Cuda的GPU信息获取支持Cuda的GPU数量获取设备属性运行展示 在GPU上分配内存把需要运行的主机内存…

scrapy出现OSError: could not get source code错误解决

出现问题如下&#xff1a; Traceback (most recent call last):File "C:\Users\admin\Desktop\crawler_scrapy_us\venv\lib\site-packages\scrapy\utils\defer.py", line 73, in mustbe_deferredresult f(*args, **kw)File "C:\Users\admin\Desktop\crawler_sc…

数据库密码实现加盐加密处理

在实际的开发中&#xff0c;我们的数据库密码一般都是明文的方式存储在数据库中&#xff0c;但是&#xff0c;这种操作非常不安全&#xff0c;容易被黑&#xff01; 那么&#xff0c;此时我们就需要对其进行加密处理&#xff0c;市面上比较常见的就是MD5加密了&#xff0c;但是…

【Linux】syscall sys_write流程摸索

这是通过tty进行摸索sys_write的流程。 在前面的博客里&#xff0c;我们可以看到基于内核C语言源代码日志打印&#xff0c;在打印的日志里边包含&#xff1a;日期&#xff0c;时间&#xff0c;当前文件所在代码目录&#xff0c;当前执行函数名&#xff0c;当前文件执行行号&am…

运维团队如何借助分布式部署提升监控效率与可靠性

随着企业IT基础设施的日益复杂和分布式架构的广泛应用&#xff0c;传统的监控解决方案已经难以满足现代运维团队的需求。在这样的背景下&#xff0c;分布式部署作为一种新型的监控架构&#xff0c;以其灵活性、可扩展性和高可用性&#xff0c;成为了运维团队提升监控效率与可靠…

C++模版基础知识与STL基本介绍

目录 一. 泛型编程 二. 函数模板 1. 概念 2. 函数模版格式 3. 函数模版的原理 4. 模版函数的实例化 (1). 隐式实例化 (2.) 显式实例化 5. 模版参数的匹配原则 三. 类模板 1. 类模板的定义格式 2. 类模板的实例化 四. STL的介绍 1. 什么是STL&#xff1f; 2. STL的版…

Linux Centos防火墙相关操作命令

防火墙基础操作 #开启防火墙 systemctl start firewalld#关闭防火墙 systemctl stop firewalld重新加载防火墙规则(改了规则后均需执行) firewall-cmd --reload防火墙开放某端口 firewall-cmd --permanent --add-port8080/tcp防火墙禁用某ip访问 firewall-cmd --permanent …

3.5-RNN文本生成

1语言模型生成文本的顺序 前面我们已经能够实现使用下图的LSTM网络进行语言建模&#xff1b; 对于一个已经在语料库上学习好的LSTM模型&#xff1b;如果语料库就只是you say goobye and i say hello&#xff1b;那么当把单词i输入到模型中&#xff0c;Time xxx层的第一个LSTM…

苍穹外卖01

0. 配置maven (仅一次的操作 1.项目导入idea 2. 保证nginx服务器运行 &#xff08;nginx.exe要在非中文的目录下&#xff09; 开启服务&#xff1a; start nginx 查看任务进程是否存在&#xff1a; tasklist /fi "imagename eq nginx.exe" 关闭ngi…

查看、指定使用的 GPU 数量和编号

在使用 PyTorch 框架时&#xff0c;可以通过以下步骤查看可用的 GPU 数量&#xff0c;指定使用的 GPU 编号&#xff0c;并在代码中体现这一点。下面以2个GPU为例&#xff1a; 目录 一、脚本代码块实现1. 查看可用的 GPU2. 指定使用 GPU 的数量和编号使用 CUDA_VISIBLE_DEVICES…

中文之美,美在辞藻富丽,也美在情感含蓄内敛。

文章目录 引言句句不提幸福,句句都是幸福句句不提释怀,句句都是释怀句句不提爱意,句句都是爱意句句不提安慰,句句都是安慰句句不提遗憾,句句都是遗憾句句不提思念,句句都是思念引言 许多句子没有将主题直抒胸臆,却通过字词间的呼应、碰撞,让人感受到“言未表而意无穷”…

第12章 Express的RESTful API开发(二)

3. 路由与中间件 在Express中&#xff0c;路由用于定义应用的各个端点&#xff08;URI&#xff09;及其处理程序。中间件是一个可以访问请求对象&#xff08;req&#xff09;、响应对象&#xff08;res&#xff09;和下一个中间件函数的函数。中间件用于处理请求之前执行一些操…

java高级——Exception异常类基本解读

java高级——Exception异常类基本解读 前情提要文章介绍继承结构异常详解1. 异常的定义2. 异常的分类3.3 异常的处理机制3.3.1 try catch finally语句3.3.2 throw关键字3.3.3 throws关键字 4. 浅谈如何有效的避免异常的发生5. 自定义异常6. 常见的RuntimeException 总结 前情提…

JDBC(Java访问数据库)

Java Database Connectivity&#xff1a;Java访问数据库的解决方案 JDBC定义了一套标准接口&#xff0c;即访问数据库的通用API&#xff0c; 不同的数据库厂商根据各自数据库的特点去实现这些接口。 JDBC希望用相同的方式访问不同的数据库&#xff0c;让具体的数据库操作与数…

HDU1056——HangOver,HDU1057——A New Growth Industry,HDU1058——Humble Numbers

目录 HDU1056——HangOver 题目描述 运行代码 代码思路 HDU1057——A New Growth Industry 题目描述 运行代码 代码思路 HDU1058——Humble Numbers 题目描述 运行代码 代码思路 HDU1056——HangOver 题目描述 Problem - 1056 运行代码 #include <iostream&…

Elasticsearch面试三道题

针对Elasticsearch的面试题&#xff0c;从简单到困难&#xff0c;我可以给出以下三道题目&#xff1a; 1. Elasticsearch的基本概念与优势 问题&#xff1a;请简要介绍Elasticsearch是什么&#xff0c;并说明它相比传统数据库的优势有哪些&#xff1f; 答案&#xff1a; El…

数学建模--整数规划和非线性规划

目录 整数规划 非线性规划 总结 整数规划中分支定界法的具体步骤和实现细节是什么&#xff1f; 初始化&#xff1a; 分支&#xff1a; 定界&#xff1a; 剪枝&#xff1a; 终止条件&#xff1a; 非线性规划中的梯度法、牛顿法和拟牛顿法的比较分析有哪些&#xff1f;…