协会网站方案,网站栅格布局,黑帽seo工具,北京通州马桥网站建设文章目录 一、Tree数据重置二、Tree拆分成二级数据1、过滤数据2、二级数据 Tree组件的数据处理往往需要使用递归#xff0c;本文归纳一下常见的数据处理情景#xff0c;持续更新#xff1b; 一、Tree数据重置 递归的标志就是寻找子元素的集合字段#xff0c;一般为children… 文章目录 一、Tree数据重置二、Tree拆分成二级数据1、过滤数据2、二级数据 Tree组件的数据处理往往需要使用递归本文归纳一下常见的数据处理情景持续更新 一、Tree数据重置 递归的标志就是寻找子元素的集合字段一般为children将所有节点依次过滤遍历过程类似于先序遍历递归得到的返回值重新组成新的children数据这个过程类似于后序遍历遍历过程主要是增加必要的属性比如value、key还可以根据节点数据动态设置icon注意展开项expandedKeys的收集根据数据自主控制 import { SmileOutlined } from ant-design/icons;
import { Button, Form, Tree } from antd;
import React, { useMemo } from react;
const treeDataTest [{ name: 0, id: 0, children: [{ name: 1, id: 0-0 }] },{name: 1,id: 1,sub: [{name: 1-0,id: 1-0,children: [{ name: 1-0-0, id: 1-0-0 },{ name: 1-0-1, id: 1-0-1 }]},{name: 2-0,id: 2-0,sub: [{name: 2-0-0,id: 2-0-0,sub: [{ name: 2-0-0-0, id: 2-0-0-0, children: [{ name: 2-0-0-0-0, id: 2-0-0-0-0 }] }]}]}]}
];
export default function TreePage() {const [form] Form.useForm();const [expandedKeys, setExpandedKeys] React.useState([]);const labelWarpBtn {offset: 6,span: 14};const onValuesChange (changedValues, allValues) {console.log(changedValues: , changedValues);console.log(allValues: , allValues);};// 转换每一个节点只区分children、sub属性、icon属性const transformData (data, expandedKeys) {data.forEach((item) {item.title item.name;item.key item.id;if (item.children) {expandedKeys.push(item.key);item.children transformData(item.children, expandedKeys);} else if (item.sub) {item.children transformData(item.sub, expandedKeys);} else {item.icon SmileOutlined /;}});return data;};// 单纯过滤数据添加属性const treeData useMemo(() {const expandedKeys [];const data transformData(treeDataTest, expandedKeys);setExpandedKeys(expandedKeys);return data;}, [treeDataTest]);return (divForm form{form} labelCol{{ span: 6 }} wrapperCol{{ span: 14 }} onValuesChange{onValuesChange}Form.Item nametree labeltree{/* fieldNames{{ title: name, key: id, children: children }} */}{/* 这里只是初步定义只能扩充三个字段想要更灵活的属性在数据层修改就好了 */}{/* 一般处理数据后还要关注expandedKeys等属性 */}Tree treeData{treeData} expandedKeys{expandedKeys} onExpand{setExpandedKeys} showIcon/Tree/Form.ItemForm.Item wrapperCol{labelWarpBtn}Button typeprimary htmlTypesubmit onClick{console.log(form.getFieldsValue())}Submit/Button/Form.Item/Form/div);
}
二、Tree拆分成二级数据
1、过滤数据 过滤不存在有效数据的节点假设num表示该节点下级存在的有效数据的数量通过num可以进行空数据过滤递归中遇到报错可以使用debugger查看问题调用次数太多使用console也无法定位 const treeDataTest [{ name: 0, id: 0, children: [{ name: 1, id: 0-0 }] },{name: 1,id: 1,sub: [{name: 1-0,id: 1-0,children: [{ name: 1-0-0, id: 1-0-0 },{ name: 1-0-1, id: 1-0-1 }]},{name: 2-0,id: 2-0,sub: [{name: 2-0-0,id: 2-0-0,sub: [{ name: 2-0-0-0, id: 2-0-0-0, children: [{ name: 2-0-0-0-0, id: 2-0-0-0-0 }] }]}]}]}
];// 过滤数据只展示存在有效数据的节点const filterData (data) {const filter (arr) {return arr.filter((item) {if (item.num 0) {// debugger;if (item.sub?.length 0) {item.sub filter(item.sub);}return true;}return false;});};return filter(JSON.parse(JSON.stringify(data)));};2、二级数据 当需要拆分成两级时需要把中间层级省略保留末端children数据假设有效数据都保存在children中设定目标数据的层级为两级就可以遍历最外层而内层递归逐个往数组里添加末端children数据 import { SmileOutlined } from ant-design/icons;
import { Button, Form, Tree } from antd;
import React, { useCallback, useMemo } from react;
const treeDataTest [{ name: 0, id: 0, num: 1, children: [{ name: 1, id: 0-0 }], sub: [] },{name: 1,id: 1,num: 3,sub: [{name: 1-0,id: 1-0,num: 2,children: [{ name: 1-0-0, id: 1-0-0 },{ name: 1-0-1, id: 1-0-1 }]},{name: 2-0,id: 2-0,num: 1,sub: [{name: 2-0-0,id: 2-0-0,num: 1,sub: [{ name: 2-0-0-0, id: 2-0-0-0, num: 1, children: [{ name: 2-0-0-0-0, id: 2-0-0-0-0 }] }]}]}]},{name: 2,id: 2,num: 0,sub: [{ name: 2-0, id: 2-0, num: 0, sub: [{ name: 2-0-0, id: 2-0-0, num: 0 }] }]}
];
export default function TreePage() {const [form] Form.useForm();const [expandedKeys, setExpandedKeys] React.useState([]);const labelWarpBtn {offset: 6,span: 14};const onValuesChange (changedValues, allValues) {console.log(changedValues: , changedValues);console.log(allValues: , allValues);};// 转换为二级树结构方便展示数据const transformChildrenOnly (data) {data.forEach((item) {item.title item.name;item.key item.id;item.icon SmileOutlined /;});return data;};const transformChildren (data, arr) {data.forEach((item) {// 这里递归的条件仅限于sub因为他是叶子节点不被需要// 如果有level层级可以采取更灵活的条件去拆分数据if (item.children) {arr.push(...transformChildrenOnly(item.children));} else if (item.sub) {transformChildren(item.sub, arr);}});return data;};const transformDataToSecondTree useCallback((data) {const newData [];const expandedKeys [];data.forEach((item) {const arr [];item.title item.name;item.key item.id;expandedKeys.push(item.key);if (item.children) {// 如果第二层就是childrenarr.push(...transformChildrenOnly(item.children));} else if (item.sub) {// 如果第二层是sub属性sub代表他是叶子节点不是最终节点transformChildren(item.sub, arr);}newData.push({ ...item, children: arr });});setExpandedKeys(expandedKeys);return newData;}, []);// 过滤数据只展示存在有效数据的节点const filterData (data) {const filter (arr) {return arr.filter((item) {if (item.num 0) {// debugger;if (item.sub?.length 0) {item.sub filter(item.sub);}return true;}return false;});};return filter(JSON.parse(JSON.stringify(data)));};// 转换为二级树结构const treeData useMemo(() transformDataToSecondTree(filterData(treeDataTest)), [treeDataTest]);return (divForm form{form} labelCol{{ span: 6 }} wrapperCol{{ span: 14 }} onValuesChange{onValuesChange}Form.Item nametree labeltree{/* fieldNames{{ title: name, key: id, children: children }} */}{/* 这里只是初步定义只能扩充三个字段想要更灵活的属性在数据层修改就好了 */}{/* 一般处理数据后还要关注expandedKeys等属性 */}Tree treeData{treeData} expandedKeys{expandedKeys} onExpand{setExpandedKeys} showIcon/Tree/Form.ItemForm.Item wrapperCol{labelWarpBtn}Button typeprimary htmlTypesubmit onClick{console.log(form.getFieldsValue())}Submit/Button/Form.Item/Form/div);
}