树形结构-CRUD接口

先看一下效果:整体的效果
   

新增效果 --默认值是 default

 修改效果 -

大致效果如上

---------------------------------------------------------------------------------------------------------------------------------
下面讲解代码如何实现的
 根据你使用的UI的框架中的树结构---形成相应的数据结构(递归形式)-如果后端给你分好了(感谢他)
这个是给我的是一个  数组包裹的对象形式 进行递归
这个我写在--一个通用的 js 导出形式  这边我需要是的是两种类型 所以分了一下(效果图上的是第一个)  
解释一下:data:后端给你的数据
                  parentId是 从0 或者 -1 开始 看你的需求 我这边是 -1

                   show:我这是区分我要的是那种类型         

递归形式走的

export function buildTree(data, parentId, show) {const result = [];data?.filter(item => item.parentId === parentId).forEach(items => {const children = buildTree(data, items.id, show);let node = ''if (!show) {node = {value: `${items.categoryName}`,key: `${items.id}`,defaultValue: `${items.categoryName}`,isEditable: false,parentId: `${items.parentId}`,children: children.length ? children : undefined,};} else {node = {value: `${items.id}`,title: `${items.categoryName}`,children: children.length ? children : undefined,};}result.push(node);});return result;
}

 这边都是实现的代码了-------可以详细看下  ---谢谢  -如果不懂-请评论


import { DownOutlined, EditOutlined, PlusOutlined, MinusOutlined, CloseOutlined, CheckOutlined } from '@ant-design/icons';
import { Input, Tree, message } from 'antd';
import React, { useEffect, useState } from 'react';
import moment from 'moment';
import { GetclubGoodsCategoryList, PostclubGoodsCategoryRemove, PostclubGoodsCategorySave, PostclubGoodsCategoryUpdate } from '@/services/commodity';
import { buildTree } from '@/utils/utils';const { TreeNode } = Tree;
// 三张图
import reduce from '@/assets/icon/reduce.png';
import addIng from '@/assets/icon/addIng.png';
import editIng from '@/assets/icon/editIng.png';
function TreeData({ onNodeClick }) {// 佛祖保佑,不会报错const [selectedNode, setSelectedNode] = useState(null);// const treeData = buildTree(data1, 0);const expandedKeyArr = ["0"];const [data, setData] = useState();const [listObj, setListObj] = useState({});let isMounted = true;const getDate = async () => {try {
//获取最初的数据  ------------接口let res = await GetclubGoodsCategoryList();if (isMounted && res && res.code == "200") {const treeData = buildTree(res.data, 0);setData(treeData);}} catch (error) {console.error("Error fetching data: ", error);}};useEffect(() => {getDate();return () => {isMounted = false;};}, []);const [expandedKeys, setExpandedKeys] = useState(expandedKeyArr);// 修改---树结构 有值---接口const onChangeUpdate = async () => {if (Object.keys(listObj).length > 0) {let res = await PostclubGoodsCategoryUpdate({categoryName: listObj.value,// parentId: listObj.key,id: listObj.key,});if (res && res.code == "200") {message.success("修改成功");
//重新获取树形结构getDate();}}}const onExpand = (expandedKeys) => {setExpandedKeys(expandedKeys);};const handleNodeClick = (node) => {setSelectedNode(node);// 进行暴露---作为一个组件调用你所点击的值对象onNodeClick(node);};const renderTreeNodes = (data, depth = 0) => {return data?.map((item) => {const title = item.isEditable ? (<div style={{display: 'flex',justifyContent: 'space-between',alignItems: 'center',}}>{/*  输入框显示 和   一个对号  一个 叉号*/}<Input placeholder="输入名称" defaultValue={item.defaultValue}onChange={(e) => onChange(e, item)} /><CheckOutlined style={{margin: '0 4px',}} onClick={() => onSave(item)} /><CloseOutlined onClick={() => onClose(item.parentKey, item.defaultValue)} /></div>) : (<div onClick={() => handleNodeClick(item)}style={{display: 'flex',justifyContent: 'space-between',alignItems: 'center',}}><divstyle={{whiteSpace: 'nowrap'}}>{item.value}</div><divstyle={{display: 'flex',flexWrap: 'nowrap',alignItems: 'center',}}>{/* <EditOutlined onClick={() => onEdit(item.key)} /><PlusOutlined onClick={() => onAdd(item.key)} />{item.parentKey !== "0" && (<MinusOutlined onClick={() => onDelete(item.key)} />)} */}{/* 两层之上就没有图标l 效果上的左边字 右边图片 */}{item.value &&<><img style={{ margin: '0 4px' }} width='15px' onClick={() => onEdit(item.key)} height='15px' src={editIng} alt="" />{depth < 2 && <img width='15px' onClick={() => onAdd(item.key)} height='15px' src={addIng} alt="" />}<img style={{ margin: '0 4px' }} onClick={() => onDelete(item.key)} width='15px' height='15px' src={reduce} alt="" /></>}</div></div>);if (item.children) {return (<TreeNode title={title} key={item.key}>{renderTreeNodes(item.children, depth + 1)}</TreeNode>);}return <TreeNode title={title} key={item.key} />;});};const onAdd = (key) => {if (expandedKeys.indexOf(key) === -1) {expandedKeys.push(key);}setExpandedKeys(expandedKeys.slice());addNode(key, data);setData([...data]);};const onEdit = (key) => {editNode(key, data);setData([...data]);};const editNode = (key, data) =>data.forEach((item) => {if (item.key === key) {item.isEditable = true;} else {item.isEditable = false;}item.value = item.defaultValue;if (item.children) {editNode(key, item.children);}});const getRandomNumber = (min = 1, max = 10000) => {return Math.floor(Math.random() * (max - min + 1)) + min;};const addNode = (key, data) =>data.forEach((item) => {if (item.key === key) {if (item.children) {item.children.push({value: "default",key: getRandomNumber(),parentKey: key,isEditable: false,showAdd: true});} else {item.children = [{value: "default",key: getRandomNumber(),parentKey: key,isEditable: false,showAdd: true},];}return;}if (item.children) {addNode(key, item.children);}});const onChange = (e, key) => {changeNode(key.parentKey ? key : key, e.target.value, data);setData([...data]);};const changeNode = (key, value, data) =>data.forEach((item) => {if (item.parentKey || item.key == key.key) {item.value = value;}if (item.children) {changeNode(key, value, item.children);}});// 保存---数据新增---接口const onSaveObj = async () => {let res = await PostclubGoodsCategorySave({categoryName: listObj.value,parentId: listObj.parentKey,})if (res && res.code === 200) {message.success('新增成功')getDate();} else {message.error('新增失败')}};useEffect(() => {if (listObj.showAdd) {onSaveObj();} else {onChangeUpdate()}}, [listObj])const onSave = (key) => {if (key.value == undefined) {message.error('请输入分类名称')return}setListObj(key)saveNode(key, data);setData([...data]);};const saveNode = (key, data) =>data.forEach((item) => {if (item.parentKey === key) {item.defaultValue = item.value;}if (item.children) {saveNode(key, item.children);}item.isEditable = false;});const onClose = (key, defaultValue) => {closeNode(key, defaultValue, data);setData([...data]);};const closeNode = (key, defaultValue, data) =>data.forEach((item, index) => {item.isEditable = false;if (item.parentKey === key) {data.splice(index, 1);item.value = defaultValue;}if (item.children) {closeNode(key, defaultValue, item.children);}});const onDelete = (key) => {deleteNode(key, data);setData([...data]);};//删除节点---接口const deleteIds = async (key) => {let data = await PostclubGoodsCategoryRemove({ids: key,})if (data && data.code === 200) {message.success('删除成功')getDate();}}const deleteNode = (key, data) =>data.forEach((item, index) => {if (item.key === key) {if (!item.showAdd) {deleteIds(key);}data.splice(index, 1);return;} else {if (item.children) {deleteNode(key, item.children);}}});return (<div style={{position: 'relative',left: '-14px'}}><Tree onExpand={onExpand} expandedKeys={expandedKeys}>{renderTreeNodes(data)}</Tree></div>);
}export default TreeData;


 

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

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

相关文章

SpringBoot发送Gmail邮件

1. 登录Gmail Gmail网址 点击右上角“小齿轮”&#xff0c;然后点击"查看所有设置" 点击“转发和 POP/IMAP”&#xff0c;按图中设置&#xff0c;然后点击保存&#xff1a; 2. 启用两步验证(https://myaccount.google.com/security) 登录上述网址&#xff0c;找…

测试FaceRecognitionDotNet报错“Error deserializing object of type int”

FaceRecognitionDotNet宣称是最简单的.net人脸识别模块&#xff0c;其内部使用Dlib、DlibDotNet、OpenCVSharp等模块实现人脸识别&#xff0c;网上有不少介绍文章。实际测试过程中&#xff0c;在调用FaceRecognition.Create函数创建FaceRecognition实例对象时&#xff0c;会报如…

易语言推箱子游戏(附带源码)

易语言推箱子游戏 易语言易语言的安装易语言功能特色易语言安装步骤易语言常见问题 导入游戏源码部分源码领取源码下期更新预报 易语言 易语言&#xff08;EPL&#xff09;是一门以中文作为程序代码编程语言&#xff0c;其以“易”著称&#xff0c;创始人为吴涛。易语言早期版…

linux同步搭建多台服务器

前言&#xff1a; 如果在安装服务器的过程中&#xff0c;需要安装多台服务器&#xff0c;同样的配置&#xff0c;同样的步骤就可以使用此方法&#xff0c;搭建集群同步安装 1.配置网卡 想要两台机器进行同步的话&#xff0c;必须网段是同样的&#xff0c;保持在同一网段并且能…

Golang:使用Base64Captcha生成数字字母验证码实现安全校验

Base64Captcha可以在服务端生成验证码&#xff0c;以base64的格式返回 为了能看到生成的base64验证码图片&#xff0c;我们借助gin go get -u github.com/mojocn/base64Captcha go get -u github.com/gin-gonic/gin文档的示例看起来很复杂&#xff0c;下面&#xff0c;通过简…

中学生学人工智能系列:如何用AI学化学

经常有读者朋友给公众号《人工智能怎么学》留言咨询如何使用人工智能学习语文、数学、英语、化学等科目。这些都是中学教师、中学生朋友及其家长们普遍关注的问题。仅仅使用留言回复的方式&#xff0c;不可能对这些问题做出具体和透彻的解答&#xff0c;因此本公众号近期将推出…

3D视觉系统实现自动化上下料操作

在竞争激烈的汽车制造行业&#xff0c;提高生产效率、降低成本并保证产品质量是企业持续发展的关键。特别是在汽车制造过程中&#xff0c;各种零部件的上下料操作占据了大量的生产时间&#xff0c;因此如何实现这些操作的自动化、高效化成为了一个亟待解决的问题。 富唯智能3D视…

C++学习/复习9--string的使用/迭代器/查找遍历修改转换容量等函数与重载运算符(建议记常用的)/练习

一、string类概要 1.1string类对象常见构造 1.2string中的元素访问 范围for与迭代器 容器与迭代器 算法与迭代器 反向迭代器 const迭代器 1.3string中的插入与查找 1.4string中的的容量与大小 注意1&#xff1a;不同编译器的对某些函数底层实现在遵守STL标准的情况下具体方式…

用任务监听RTOS各任务的运行状态

使用rtos时内存对于单片机来说总是非常抠搜的。 任务分配多了浪费&#xff0c;少了跑不动。 最近看到这个监听任务还是很好用的。 废话不多说。开始操作 第一步在配置文件中打开这几个宏 #define configUSE_TRACE_FACILITY 1 /*为1时启用可视化跟踪调试*/ #define conf…

两整数之和 ---- 位运算

题目链接 题目: 分析: 题目中要求不能使用-, 考虑到我们的位运算异或^, 是无进位加法, 可以使用如果是无进位加法, 那么我们就要找到进位, 并进行计算, 进位只有1和1相加时才会产生进位1, 而0和1相加无进位, 进位为0, 那么我们就想到了&运算, 1&1 1, 0&1 0, 所…

07-操作元素(键盘和鼠标事件)

在前面的文章中重点介绍了一些元素的定位方法&#xff0c;定位到元素后&#xff0c;就需要操作元素了。本篇总结了web页面常用的一些操作元素方法&#xff0c;可以统称为行为事件。 一、简单操作 点击按钮&#xff08;鼠标左键&#xff09;&#xff1a;click()清空输入框&…

基础—SQL—DQL(数据查询语言)排序查询

一、引言 排序查询这里面涉及的关键字&#xff1a;ORDER BY。在我们日常的开发中&#xff0c;这个是很常见的&#xff0c;比如打开一个网购的商城&#xff0c;这里面可以找到一个销量的排序、综合的排序、价格的排序&#xff08;升序、降序&#xff09;等等。接下来就学习这一部…

mac电脑用谷歌浏览器对安卓手机H5页面进行inspect

1、mac上在谷歌浏览器上输入 chrome://inspect 并打开该页面。 2、连接安卓手机到Mac电脑&#xff1a;使用USB数据线将安卓手机连接到Mac电脑。 3、手机上打开要的h5页面 Webview下面选择要的页面&#xff0c;点击inspect&#xff0c;就能像谷歌浏览器页面打开下面的页面&#…

​​​​​​​Beyond Compare 3密钥被撤销的解决办法

首先&#xff0c;BCompare3的链接如下 链接&#xff1a;https://pan.baidu.com/s/1vuSxY0cVQCt0-8CpFzUhvg 提取码&#xff1a;8888 --来自百度网盘超级会员V7的分享 1.问题现象 激活之后在使用过程中有时候会出现密钥被撤销的警告&#xff0c;而且该工具无法使用&#xff…

命令模式(行为型)

目录 一、前言 二、命令模式 三、总结 一、前言 命令模式&#xff08;Command Pattern&#xff09;是一种行为型设计模式&#xff0c;命令模式将一个请求封装为一个对象&#xff0c;从而可以用不同的请求对客户进行参数化&#xff1b;对请求排队或记录请求日志&#xff0c;以…

小角楼是怎样成为清廷御酒的?

执笔 | 扬 灵 编辑 | 古利特 “酒史千年远&#xff0c;酒花百代香&#xff0c;天府多佳酿&#xff0c;美酒驻平昌。” 对四川省巴中市平昌县而言&#xff0c;白酒是经济发展的重要产业之一&#xff0c;好山好水出好酒&#xff0c;优良的地质、水源、气候、土壤等条件以及悠久…

算法(十一)贪婪算法

文章目录 算法简介算法概念算法举例 经典问题 -背包问题 算法简介 算法概念 贪婪算法&#xff08;Greedy&#xff09;是一种在每一步都采取当前状态下最好的或者最优的选择&#xff0c;从而希望导致结果也是全局最好或者最优的算法。贪婪算法是当下局部的最优判断&#xff0c…

无忧易售ERP:解锁TikTok平台订单处理新效能,赋能跨境电商新未来

在这个全球化电商飞速发展的时代&#xff0c;TikTok作为新兴的电商蓝海&#xff0c;正吸引着无数商家的目光。然而&#xff0c;如何在竞争激烈的市场中脱颖而出&#xff0c;高效管理订单&#xff0c;提升顾客体验&#xff0c;成为每个商家必须面对的课题。无忧易售ERP&#xff…

NSS题目练习5

[NISACTF 2022]babyupload 打开后尝试上传php&#xff0c;jpg&#xff0c;png文件都没成功 查看源代码发现有个/source文件 访问后下载压缩包发现有一个python文件 搜索后知道大致意思是&#xff0c;上传的文件不能有后缀名&#xff0c;上传后生成一个uuid&#xff0c;并将uuid…

基于深度学习的模糊认知图方法

1 文章信息 文章题目为“Deep Fuzzy Cognitive Maps for Interpretable Multivariate Time Series Prediction”&#xff0c;该文于2019年发表于“IEEE TRANSACTIONS ON FUZZY SYSTEMS”。文章提出了深度模糊认知图&#xff08;FCM&#xff09;用于多变量时间序列预测&#xff…