预设:树形结构数据树形为value、children、label
- 格式化树形数据
// 格式化树形数据
// 参数1:树形数据源
// 参数2:需要替换的属性对象(props的key为替换后的属性名,value为需要替换的属性名)
// 参数2示例: props = { value: 'value1', label: 'label1', children: 'children1' },
export const formateTreeData = (data, props = {}) => {
const currentProps = { children: 'children', ...props };
const options = JSON.parse(JSON.stringify(data));
if (!Array.isArray(options)) return [];
for (const item of options) {
for (const prop in currentProps) {
if (prop === 'children') {
if (Array.isArray(item[currentProps[prop]]) && item[currentProps[prop]].length) {
item[prop] = formateTreeData(item[currentProps[prop]], currentProps);
}
} else {
item[prop] = item[currentProps[prop]];
delete item[currentProps[prop]];
}
}
}
return options;
};
- 获取当前节点下所有子节点
// 获取当前节点下所有叶子节点
// 参数:当前节点的对象
const getAllLeafNodes = (data) => {
let { children } = data;
let arr = [];
if (!children) {
// 本身就是叶子节点
return [data];
}
for (let item of children) {
if (item.children && Array.isArray(item.children) && item.children.length) {
arr.push(...getAllLeafNodes(item));
} else {
arr.push(item);
}
}
return arr;
};
- 查找目标value在树中的对象
// 查找目标value,在树中的对象Obj
// 参数1:需要查找的value,可以是单个,也可以是数组,即查询多个,此时返回值也为数组
// 参数2:树形数据源
const findInTreeData = (ids, data) => {
if (!Array.isArray(data)) return;
// 判断是否为多选
let isMultiple = Array.isArray(ids);
// 目标对象(可能为string,可能为array)
let goal = null;
if (isMultiple) {
goal = [];
for (let id of ids) {
let res = findInTreeData(id, data);
if (res) {
goal.push(res);
}
}
} else {
// 遍历树
for (let item of data) {
let { value, children } = item;
if (value === ids) {
goal = item;
break;
} else {
if (children && Array.isArray(children) && children.length) {
goal = findInTreeData(ids, children);
if (goal) break;
}
}
}
}
return goal;
};
- 根据主键获取从顶层父节点至该节点的路径(用到了上述方法3,请引入)
import { isObject } from "lodash";
// 参数1:查询目标的主键id
// 参数2:树形数据源
// 返回结果:从顶层节点 至 目标节点的路径节点数组。
const findPathByValue = (value, data) => {
let arr = [];
// findInTreeData为上述方法3
let currentNode = findInTreeData(value, data);
// 判断当前节点是否找到,找到则加入数组
if (isObject(currentNode) && Object.keys(currentNode).length) {
arr.unshift(currentNode);
}
// 判断当前节点是否有父节点,若有则继续递归查找父节点id所在node
if (currentNode.parentId) {
arr.unshift(...findPathByValue(currentNode.parentId, data));
}
return arr;
};
为了适用通用大部分情况,返回的是路径数组,可以根据实际情况进行处理。
例如:需要返回路径名称,可以通过arr.map(item => item.label),即可得到路径名称数组。
网友评论