实战react+ts+antd遇见的问题之自定义树形结构

news2024/9/28 15:25:58

目录

  • 自定义编辑树
  • 搜索树形结构
    • 搜索算法原理
  • 实时更改数据界面不随之发生变化

自定义编辑树

需求要求在每个节点的后面加上新增,编辑,删除按钮,并且能够点击编辑title的显示变成input输入框,antd的案例中没有这种情况,但是antd的api中给了titleRender可以自定义title样式。
在这里插入图片描述

<Tree
			...
            titleRender={onTitleRender}
			...
        >
</Tree>
 const onTitleRender = (item: any) => {      //  title渲染函数
        let content
        let icon
        let beforeIcon
        if (item.key === pickedEdit) {
            content = (<Input
                // value={item.title}
                defaultValue={item.title}
                onChange={(e) => onChange(e, item.key)}
                onPressEnter={(e) => onPressEnter(e, item.key)}
                onBlur={(e) => onPressEnter(e, item.key)}
            />)
        } else {
            content = (<div onClick={(e) => chooseContent(e, item.title)}>{item.title}</div>)
        }


        if (!item.isLeaf) { //  该节点为父节点
            beforeIcon = (<FolderOpenTwoTone twoToneColor="#cdb228" style={{ marginRight: '5px' }} />)
            icon = (
                <span style={{ display: 'flex' }}>
                    <PlusOutlined style={{ marginLeft: 10, color: '#409EFF' }} onClick={() => onAdd(item.key)} />
                    <EditOutlined style={{ marginLeft: 10, color: '#409EFF' }} onClick={() => onEdit(item.key)} />
                    <CloseOutlined style={{ marginLeft: 10, color: '#409EFF' }} onClick={() => onDelete(item.key)} />
                </span>
            )

        } else {    //  该节点为叶子节点
            beforeIcon = (<FileTextOutlined style={{ marginRight: '5px' }} />)
            icon = (
                <span style={{ display: 'flex' }}>
                    <EditOutlined style={{ marginLeft: 10, color: '#409EFF' }} onClick={() => onEdit(item.key)} />
                    <CloseOutlined style={{ marginLeft: 10, color: '#409EFF' }} onClick={() => onDelete(item.key)} />
                </span>
            )
        }
        return (
            <div style={{ display: 'flex', alignItems: 'center' }}>
                {beforeIcon}
                {content}
                {icon}
            </div>
        );

    };

这里我设置了一个全局变量pickedEdit来记录当前正在编辑的节点的key,当编辑的key有值后,key相等的title就会变成input框
我这里的判断是因为我们要求树只有三层,所以不给叶子节点add功能,也用不同的图标区分是否是叶子节点。

搜索树形结构

首先,返回的node肯定要加一个<Search style={{ marginBottom: 8 }} placeholder=“搜索” onChange={onChangeSearch} />
其次,是搜索框change内容时触发的函数,如下

// 搜索框的change事件触发函数
    const onChangeSearch = (e: any) => {
        const { value } = e.target;
        const expandedKeys = dataList
            .map((item: any) => {
                if (item.title.indexOf(value) > -1) {
                    return getParentKey(item.key, treeData);
                }
                return null;
            })
            .filter((item: any, i: any, self: any) => item && self.indexOf(item) === i);

        setExpandedKeys(expandedKeys);
        setSearchValue(value);
        setAutoExpandParent(true);
    };
//  生成key的数组
    const generateList = (data: any) => {
        for (let i = 0; i < data.length; i++) {
            const node = data[i];
            const { key, title } = node;
            dataList.push({ key, title: title });
            if (node.children) {
                generateList(node.children);
            }
        }
    };
    generateList(treeData);
    
    //  查询父节点的key
    //@ts-ignore
    const getParentKey = (key: any, tree: any) => {
        let parentKey;
        for (let i = 0; i < tree.length; i++) {
            const node = tree[i];
            if (node.children) {
                if (node.children.some((item: any) => item.key === key)) {
                    parentKey = node.key;
                } else if (getParentKey(key, node.children)) {
                    parentKey = getParentKey(key, node.children);
                }
            }
        }
        return parentKey;
    };

最后也是最最重要的:搜索算法

// 循环遍历搜索关键字
    const loop = (data: any) =>
        data.map((item: any) => {
            //  将title分成三部分,中间的是搜索命中的内容
            const index = item.title.indexOf(searchValue);
            const beforeStr = item.title.substr(0, index);
            const afterStr = item.title.substr(index + searchValue.length);
            const title =
                index > -1 ? (
                    <span>
                        {beforeStr}
                        <span style={{ color: '#f50' }}>{searchValue}</span>
                        {afterStr}
                    </span>
                ) : (
                    <span>{item.title}</span>
                );
            if (item.children) {
                return { title, key: item.key, children: loop(item.children) };
            }

            return {
                title,
                key: item.key,
                isLeaf: item.isLeaf
            };
        });

搜索算法原理

将title分为三部分,beforeStr,index和afterStr,其中index是搜索的内容;
如果index存在,就将index的内容样式改变,变成红色。
这里的搜索顺序是深度优先。

实时更改数据界面不随之发生变化

联调的时候突然发现,改完数据后上传,然后用setState更新treedata,这时界面上的数据没有变化,没更新?
想起来之前准备面试的时候学的深拷贝和浅拷贝,tree在ts中是以object类型保存的,那么setState会不会只是个浅拷贝,只存了这个变量的地址,所以它地址没变就没有重新渲染,那么就可以采用一些方式让他进行深拷贝,也可以改变一下它的地址,比如下面我采取的方法:

let temp = [...treeData]
setTreeData(temp)

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

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

相关文章

逍遥自在学C语言 | 指针函数与函数指针

前言 在C语言中&#xff0c;指针函数和函数指针是强大且常用的工具。它们允许我们以更灵活的方式处理函数和数据&#xff0c;进而扩展程序的功能。 本文将介绍指针函数和函数指针的概念&#xff0c;并讲解一些常见的应用示例。 一、人物简介 第一位闪亮登场&#xff0c;有请…

金士顿U盘无法识别的修复软件,方便好用

一、PD V1.16 先打开“PDx16.exe”这个软件&#xff0c;插入U盘。就会在“DEVICE 1”那里检测到U盘&#xff08;如果没有&#xff0c;就用另外的软件&#xff09;。然后按“全部开始”。当完成好&#xff0c;再重新插入U盘。 二、2090&2090E_V1.6.9_普通版070628 1、插入…

工业机器人运动学与Matlab正逆解算法学习笔记(用心总结一文全会)(二)

文章目录 机器人逆运动学※ 代数解、几何解&#xff0c;解析解&#xff08;封闭解&#xff09;、数值解的含义与联系○ 代数解求 θ 1 \theta_1 θ1​、 θ 2 \theta_2 θ2​、 θ 3 \theta_3 θ3​※参考资料 求解 θ 1 \theta_1 θ1​ 求解 θ 3 \theta_3 θ3​ 求解 θ 2 \t…

JUC高级-0620

8. CAS 原子类&#xff1a;Atomic没有CAS之前&#xff1a;多线程环境不使用原子类保证线程安全i&#xff08;基本数据类型&#xff09;&#xff0c;可以使用synchronized&#xff0c;但是很重有CAS之后&#xff1a; 使用AtomicInteger.getAndIncrement这样的API&#xff0c;保…

ARM的半主机模式(Semihosting)

本文介绍ARM的半主机模式&#xff0c;并介绍在MCU进行调试时其他的调试方法和手段。 1.ARM半主机模式(Semihosting) ARM Semihosting是ARM平台的一个独特功能&#xff0c;它允许使用主机上的输入和输出函数&#xff0c;通过硬件调试器转发到微控制器&#xff0c;通过挂接到I/…

网络解析----faster rcnn

Faster R-CNN&#xff08;Region-based Convolutional Neural Network&#xff09;是一种基于区域的卷积神经网络用于目标检测任务的模型。它是一种两阶段的目标检测方法&#xff0c;主要包含以下几个步骤&#xff1a; Region Proposal Network&#xff08;RPN&#xff09;: F…

c++ vector的扩容机制

1、当向vector push_back一个元素时&#xff0c;如果此时元素个数超过了vector的容量&#xff0c;会触发扩容 2、扩容的过程是&#xff1a;开辟新空间->拷贝旧空间的元素->释放旧空间 3、扩容过程中开辟新空间的大小影响着往vector插入元素的效率&#xff1a; 如果新空…

软件系统三基座之三:用户管理

软件系统三基座包含&#xff1a;权限管理、组织架构、用户管理。 基于权限控制、组织搭建&#xff0c;用户可以批量入场。 一、用户管理 在系统构建中&#xff0c;权限控制、组织搭建&#xff0c;对于普通用户都是不可见的。 权限控制&#xff0c;在系统搭建时&#xff0c;就会…

电商网站Web自动化测试实战( 编写京东搜索脚本python+selenium框架)

电商网站Web自动化测试实战&#xff08; 编写京东搜索脚本&#xff09; 1&#xff0c;打开京东页 京东首页地址&#xff1a;京东(JD.COM)-正品低价、品质保障、配送及时、轻松购物&#xff01;&#xff0c;故进入京东首页如下&#xff1a; 2&#xff0c;打开浏览器开发者模式…

Doris-简介、架构、编译、安装和数据表的基本使用

目录 1、Doris简介2、Doris网址3、Doris架构3、编译和安装 3.1、软硬件需求3.2、编译 3.2.1、安装Docker环境3.2.2、使用Docker 开发镜像编译3.3、集群部署 3.3.1、创建目录并拷贝编译后的文件3.3.2、部署 FE 节点3.3.3、配置 BE 节点3.3.4、在 FE 中添加所有 BE 节点3.3.5、启…

最小生成树的拓展应用

1.新的开始 信息学奥赛一本通&#xff08;C版&#xff09;在线评测系统 (ssoier.cn)http://ybt.ssoier.cn:8088/problem_show.php?pid1488 假如自己建个发电站相当于从一个虚拟原点向他有条边&#xff0c;然后做跑一遍最小生成树即可 #include<bits/stdc.h> using nam…

【云原生】Docker部署/容器加速器(最新版)

目录 初时Docker和部署 1.什么是Docker 2.容器和虚拟化的区别 3.部署Docker 1.卸载历史版本 2.设置存储库 3.安装Docker最新引擎 4.安装Docker特定安装引擎 1.先查看当前docker-ce都有那些版本 2.替换为所需版本&#xff0c;然后运行以下命令 要安装的命令&#xff1a; 5.启动D…

Python入门教程:掌握for循环、while循环、字符串操作、文件读写与异常处理等基础知识

文章目录 for循环while循环字符串操作访问字符串中的字符切片总结字符串拼接 文件读写try...except 异常处理函数模块和包类和面向对象编程完结 for循环 在 Python 中&#xff0c;for 循环用于遍历序列&#xff08;list、tuple、range 对象等&#xff09;或其他可迭代对象。for…

AI建模可以智能到什么程度?

2023年年初&#xff0c;我们被AIGC&#xff08;人工智能生产内容&#xff09;撞了个满怀&#xff0c;从AI绘画、AI写作、AI配音&#xff0c;到AI建模&#xff0c;似乎每个行业的内容创作者都被AI“击中了膝盖”。AI技术发展迅速&#xff0c;前段时间&#xff0c;国内外各大公司…

使用esp32+micropython+microdot搭建web(http+websocket)服务器(超详细)第三部分

使用esp32micropythonmicrodot搭建web(httpwebsocket)服务器&#xff08;超详细&#xff09;第三部分 microdot文档速查 什么是Microdot?Microdot是一个可以在micropython中搭建物联网web服务器的框架micropyton文档api速查 Quick reference for the ESP32 实现websocket服务…

优雅组合,高效交互:Gradio Combining Interfaces模块解析

❤️觉得内容不错的话&#xff0c;欢迎点赞收藏加关注&#x1f60a;&#x1f60a;&#x1f60a;&#xff0c;后续会继续输入更多优质内容❤️ &#x1f449;有问题欢迎大家加关注私戳或者评论&#xff08;包括但不限于NLP算法相关&#xff0c;linux学习相关&#xff0c;读研读博…

Jdk9版本以上如何查看java对象所占内存大小

想要查看java对象在运行时的实际占用内存大小。网上大部分方法都是雷同&#xff0c;都是出自 查看java对象所占内存大小-云社区-华为云 这里面的提供的4种方法仅仅适合jdk8及以下版本。 如果项目使用的是dk11、jdk18等高级版本就无法使用&#xff0c;上面帖子中第一种和第二…

蓝奥声核心技术—— 用电异常监控技术

1.技术背景 用电异常监控技术主要通过电能监测节点作为目标监测节点对其关联绑定的用电负载对象的异常状态进行快速响应与准确监控&#xff0c;以解决用电监控的安全性问题。该项技术涉及无线物联网边缘智能与测控的技术领域&#xff0c;主要涉及面向电能监测及安全监控的边缘…

编译原理笔记12:自上而下语法分析(2)非递归预测分析器、FIRST FOLLOW 集合计算

目录 使用预测分析器的自上而下分析格局 使用预测分析器进行分析的实例FIRST、FOLLOW 集合的构造FIRST 集合FOLLOW 集合 使用预测分析器的自上而下分析 使用预测分析器进行的自上而下分析是非递归的。预测分析器模型其实是一种 PDA&#xff08;下推自动机&#xff0c;Pushdown…

uni-number-box【数字输入框组件】,change事件 自定义传参

关键代码&#xff1a; change"(value)>{twobindChange(item,value)}" <uni-number-box :min"1" :value"item.num" change"(value)>{twobindChange(item,value)}" /><script>//数量选择twobindChange(item, value) …