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

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属性

在这里插入图片描述

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 文件上传漏洞(ctfshow web151-161)
  • 16现代循环神经网络—深度循环与双向循环
  • 52、PHP 实现选择排序
  • 点脂成金携手北京新颜兴医疗美容医院,共启战略合作新篇章
  • Android 10.0 Launcher 启动流程
  • 开源消息队列比较
  • 【前端 15】Vue生命周期
  • 数据库实验:SQL Server基本表单表查询
  • SpringBoot集成Sharding-JDBC实现分库分表
  • 【计算机网络】TCP协议详解
  • linux环境下重新编译opencv的安卓动态链接库opencv_java4.so文件
  • TransmittableThreadLocal跟InheritableThreadLocal使用
  • 搭建自己的金融数据源和量化分析平台(一):系统架构设计
  • 【初阶数据结构篇】顺序表的实现(赋源码)
  • Mysql中DML的几种操作
  • 深入了解以太坊
  • 2019年如何成为全栈工程师?
  • AHK 中 = 和 == 等比较运算符的用法
  • CentOS 7 防火墙操作
  • electron原来这么简单----打包你的react、VUE桌面应用程序
  • github从入门到放弃(1)
  • GitUp, 你不可错过的秀外慧中的git工具
  • Java 11 发布计划来了,已确定 3个 新特性!!
  • laravel5.5 视图共享数据
  • ng6--错误信息小结(持续更新)
  • node.js
  • Python十分钟制作属于你自己的个性logo
  • react-native 安卓真机环境搭建
  • React-redux的原理以及使用
  • Sequelize 中文文档 v4 - Getting started - 入门
  • spring cloud gateway 源码解析(4)跨域问题处理
  • 大快搜索数据爬虫技术实例安装教学篇
  • 开发了一款写作软件(OSX,Windows),附带Electron开发指南
  • 前端之Sass/Scss实战笔记
  • 悄悄地说一个bug
  • 如何打造100亿SDK累计覆盖量的大数据系统
  • 腾讯大梁:DevOps最后一棒,有效构建海量运营的持续反馈能力
  • 微信如何实现自动跳转到用其他浏览器打开指定页面下载APP
  • 终端用户监控:真实用户监控还是模拟监控?
  • 如何在 Intellij IDEA 更高效地将应用部署到容器服务 Kubernetes ...
  • ​​​​​​​开发面试“八股文”:助力还是阻力?
  • ​补​充​经​纬​恒​润​一​面​
  • ​一文看懂数据清洗:缺失值、异常值和重复值的处理
  • ​用户画像从0到100的构建思路
  • #etcd#安装时出错
  • #Z2294. 打印树的直径
  • $ git push -u origin master 推送到远程库出错
  • $.each()与$(selector).each()
  • (C语言)共用体union的用法举例
  • (day6) 319. 灯泡开关
  • (HAL)STM32F103C6T8——软件模拟I2C驱动0.96寸OLED屏幕
  • (LNMP) How To Install Linux, nginx, MySQL, PHP
  • (附源码)ssm智慧社区管理系统 毕业设计 101635
  • (函数)颠倒字符串顺序(C语言)
  • (三)终结任务