tree组件实现折叠与展开功能(方式1 - expandedTree计算属性)

本示例节选自vue3最新开源组件实战教程大纲(持续更新中)的tree组件开发部分。考察响应式对象列表封装和computed计算属性的使用,以及数组reduce方法实现结构化树拍平处理的核心逻辑。

实现思路

第一种方式:每次折叠或展开后触发扁平化列表的重新计算和渲染。

第二种方式:每次折叠或展开后出发其所有子节点的visible计算属性重新计算,用v-show进行动态渲染。

这里我们先讨论第一种方案的实现。

实现方式

在循环遍历树节点时,增加要渲染的内容:

<div class='juan-tree-node' key=... style=...>
  {/* 渲染节点前的内容,父节点需要展示隐藏或展开按钮,叶子节点留出空的span来占据位置 */}
  {node.isLeaf ? (
    <span class='mr-1 inline-block w-[20px]'></span>
  ) : (
    <button onClick={() => toggleNode(node)} class='mr-1 inline-block h-[18px] w-[20px]'>
      {node.expanded ? <span>-</span> : <span>+</span>}
    </button>
  )}
  {node[labelName as 'label']}
</div>

节点的展开与折叠操作,注意需要操作响应式的对象,这样会触发计算属性的重新计算:

// 将树拍平的扁平化列表结构,包装成响应式列表,操作一个节点的展开与折叠,其实操作的是响应式列表中的一个元素,以便触发expandedTree计算属性重新计算。
const flatData = ref(generateFlatTree(data, optionProps))
const toggleNode = (node: IFlatTreeNode) => {
  // 注意,这里操作的其实是响应式列表中的一个元素,改变其属性会触发expandedTree重新计算
  node.expanded = !node.expanded
}
// 该计算属性用于计算已经展开的所有节点,包括手动设置expanded属性为false的父节点,而排除掉扁平化列表中折叠节点的所有子孙节点。
const expandedTree = computed(() => {
  const result = []
  for (let i = 0; i < flatData.value.length; i++) {
    const item = flatData.value[i]
    // 如果是父节点并且非展开(默认是折叠的)则跳过其所有子孙节点。
    if (!item.isLeaf && item.expanded !== true) {
      // 跳过内部所有节点
      i += item.length!
    }
    result.push(item)
  }
  return result
})

不要忘了,tree模板中遍历的对象为expandedTree.value

跳过多少个需要隐藏的子节点列表呢?

这是expandedTree计算属性实现中的关键点,咱们的实现是给IFlatTreeNode上加一个length属性,

// 扩展的扁平化节点
export interface IFlatTreeNode extends ITreeNode {
  ...
  length?: number // 设置其子孙节点的长度
}

该属性值是在generateFlatTree拍平函数中设置的:

在这里插入图片描述
执行效果:
在这里插入图片描述

存在的问题

存在的问题

  1. expandedTree计算属性每次都要整体进行计算,且对变化的部分做重新渲染
  2. IFlatTreeNodelength属性是在拍平函数中设置死的,append节点后,这个属性值应该是变化的。

下一小节,我们讲采用第二种实现方式来规避这个问题。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【LeetCode】对称二叉树

目录 一、题目二、解法完整代码 一、题目 给你一个二叉树的根节点 root &#xff0c; 检查它是否轴对称。 示例 1&#xff1a; 输入&#xff1a;root [1,2,2,3,4,4,3] 输出&#xff1a;true 示例 2&#xff1a; 输入&#xff1a;root [1,2,2,null,3,null,3] 输出&#…

洗地机哪个牌子好性价比高又实惠?四款洗地机好洗地机的品牌推荐

在追求家居清洁效率与成本效益并重的今天&#xff0c;选择一款性价比高且实惠的洗地机显得尤为重要。市场上洗地机品牌琳琅满目&#xff0c;至于洗地机哪个牌子好性价比高又实惠成为很多人心中的疑问。为此&#xff0c;我们精心搜集并推荐四款洗地机好洗地机的品牌&#xff0c;…

数据结构之跳表SkipList、ConcurrentSkipListMap

概述 SkipList&#xff0c;跳表&#xff0c;跳跃表&#xff0c;在LevelDB和Lucene中都广为使用。跳表被广泛地运用到各种缓存实现当中&#xff0c;跳跃表使用概率均衡技术而不是使用强制性均衡&#xff0c;因此对于插入和删除结点比传统上的平衡树算法更为简洁高效。 Skip lis…

【学习笔记】无人机系统(UAS)的连接、识别和跟踪(七)-广播远程识别码(Broadcast Remote ID)

目录 引言 5.5 广播远程识别码&#xff08;Broadcast Remote ID&#xff09; 5.5.1 使用PC5的广播远程识别码 5.5.2 使用MBS的广播远程识别码 引言 3GPP TS 23.256 技术规范&#xff0c;主要定义了3GPP系统对无人机&#xff08;UAV&#xff09;的连接性、身份识别、跟踪及…

达梦数据库DM8-索引篇

目录 一、前景二、名词三、语法1、命令方式创建索引1.1 创建索引空间1.2.1 创建普通索引并指定索引数据空间1.2.2 另一种没验证&#xff0c;官方写法1.3 复合索引1.4 唯一索引1.5 位图索引1.6 函数索引 2、创建表时候创建索引3、可视化方式创建索引3.1 打开DM管理工具3.2 找到要…

appium2.0 执行脚本遇到的问题

遇到的问题&#xff1a; appium 上的日志信息&#xff1a; 配置信息 方法一 之前用1.0的时候 地址默认加的 /wd/hub 在appium2.0上&#xff0c; 服务器默认路径是 / 如果要用/wd/hub 需要通过启动服务时设置基本路径 appium --base-path/wd/hub 这样就能正常执行了 方法二…

利用request + BeautifulSoup 模块批量爬取内容,实现批量获取书名对应的豆瓣评分

文章目录 代码代码解释控制台输出结果 代码 #-*- coding:utf-8 -*- from bs4 import BeautifulSoup import requests, time, jsonheaders {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.39…

初识godot游戏引擎并安装

简介 Godot是一款自由开源、由社区驱动的2D和3D游戏引擎。游戏开发虽复杂&#xff0c;却蕴含一定的通用规律&#xff0c;正是为了简化这些通用化的工作&#xff0c;游戏引擎应运而生。Godot引擎作为一款功能丰富的跨平台游戏引擎&#xff0c;通过统一的界面支持创建2D和3D游戏。…

jmeter-beanshell学习11-从文件获取指定数据

参数文件里的参数可能过段时间就不能用了&#xff0c;需要用新的参数。如果有多个交易&#xff0c;读不同的参数文件&#xff0c;但是数据还是一套&#xff0c;就要改多个参数文件。或者只想执行参数文件的某一行数据&#xff0c;又不想调整参数文件顺序。 第一个问题目前想到…

Transformer 翻译

Attention Is All You Need Ashish Vaswani∗ Google Brain avaswanigoogle.com Noam Shazeer∗ Google Brain noamgoogle.com Niki Parmar∗ Google Research nikipgoogle.com Jakob Uszkoreit∗ Google Research uszgoogle.com Llion Jones∗ Google Research lliongoogle.c…

mysql字符类型字段设置默认值为当前时间

-- 2024-07-22 10:22:20 select (DATE_FORMAT(CURRENT_TIMESTAMP, %Y-%m-%d %H:%i:%s)); ALTER TABLE tablename MODIFY COLUNN CREATE_DATE varchar (23) DEFAULT(DATE_FORMAT(CURRENT_TIMESTAMP, %Y-%m-%d %H:%i:%s)) COMMENT "创建日期;

力扣最热一百题——2.字母异位词分组

目录 题目链接&#xff1a;49. 字母异位词分组 - 力扣&#xff08;LeetCode&#xff09; 题目 示例 提示 解法一&#xff1a;哈希表排序 思路 代码实现 解法二&#xff1a;记录字母出现的次数哈希表 思路 代码实现 总结 话不多说直接上题目。 题目链接&#xff1a;…

spring MVC 简单案例(3)我的书架管理系统

一、创建项目 最后修改以下 spring 版本 为 2.7.17 Java 版本为 8 同时在 <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:xsi"http://www.w3.org/2001/XMLSchema-instanc…

[Python库](3) Arrow库

目录 1.简介 2.安装 3.函数 3.1.获取当前UTC时间( 世界协调时时间 ) 3.2.格式化日期 3.3.创建Arrow对象 3.4.时间改变 3.5.获取时间戳 3.6.时区改变 4.小结 1.简介 Arrow库是一个Python库&#xff0c;提供了一套用于处理日期和时间的API。Arrow库特别适合在需要进行大…

【算法专题】双指针算法之611. 有效三角形的个数(力扣)

欢迎来到CILMY23的博客 &#x1f3c6;本篇主题为&#xff1a;双指针算法之611. 有效三角形的个数&#xff08;力扣&#xff09; &#x1f3c6;个人主页&#xff1a;CILMY23-CSDN博客 &#x1f3c6;系列专栏&#xff1a;Python | C | C语言 | 数据结构与算法 | 贪心算法 | Li…

web安全之跨站脚本攻击xss

定义: 后果 比如黑客可以通过恶意代码,拿到用户的cookie就可以去登陆了 分类 存储型 攻击者把恶意脚本存储在目标网站的数据库中(没有过滤直接保存)&#xff0c;当用户访问这个页面时&#xff0c;恶意脚本会从数据库中被读取并在用户浏览器中执行。比如在那些允许用户评论的…

Android APP 基于RecyclerView框架工程(知识体系积累)

说明&#xff1a;这个简单的基于RecyclerView的框架作用在于自己可以将平时积累的一些有效demo整合起来&#xff08;比如音视频编解码的、opengles的以及其他也去方向的、随着项目增多&#xff0c;工程量的增加&#xff0c;后期想高效的分析和查找并不容易&#xff09;&#xf…

java题目之评委打分

public class Main5 {public static void main(String[] args) {//在唱歌比赛中&#xff0c;有6名评委打分&#xff0c;分数范围是[0-100]之间的整数//选手的最后得分为&#xff1a;去掉最高分&#xff0c;最低分后的4个评委的平均分&#xff0c;请完成上述过程中并计算选手的得…

python实现责任链模式

把多个处理方法串成一个list。下一个list的节点是上一个list的属性。 每个节点都有判断是否能处理当前数据的方法。能处理&#xff0c;则直接处理&#xff0c;不能处理则调用下一个节点&#xff08;也就是当前节点的属性&#xff09;来进行处理。 Python 实现责任链模式&#…

若依前后端获取当前用户

后端 Autowired private TokenService tokenService;LoginUser loginUser tokenService.getLoginUser(); sysInquiry.setCreateBy(loginUser.getUsername()); sysInquiry.setCreateTime(DateUtils.getNowDate()); 前端 获取使用 const nickName this.$store.state.user.nick…