案列一如下:
需求分析
1,根据fatherTreeCode判断是不是父级,为空是父级,然后处理成树形层级关系。
2,完成树形结构后再树形数据里面添加对应的key和value值进行显示。
原数据
const treeData = [
{
capList: [],
fatherTreeCode: "",
isLeaf: "0",
showSeqno: "1",
treeCode: "TRE0rv",
treeLevel: "1",
treeName: "根目录",
},
{
capList: [],
fatherTreeCode: "TRE0rv",
isLeaf: "0",
showSeqno: "4",
treeCode: "TRE0sw",
treeLevel: "2",
treeName: "物联网",
},
{
fatherTreeCode: "TRE0rv",
isLeaf: "1",
showSeqno: "4",
treeCode: "TRE0xw",
treeLevel: "2",
treeName: "云网业务",
capList: [
{
code: "del-",
id: "8c15d2488ad24d55946e6ce0f5ea3f40",
name: "5G切片开通",
treeLevel: "12",
},
{
code: "netpe-resource-allocation-request",
id: "35202810e96442fda4d6aaa61122986b",
name: "5G资源预占",
treeLevel: "13",
},
],
},
];
代码如下:
function tree (data) {
const obj = {}
for (const item of data) {
obj[item.treeCode] = item
}
const result = []
for (const item of data) {
if (obj[item.fatherTreeCode]) {
if (!obj[item.fatherTreeCode].capList) {
obj[item.fatherTreeCode].capList = []
}
obj[item.fatherTreeCode].capList.push(item)
} else {
result.push(item)
}
}
return result
}
let list = tree(treeData);
console.log(list, 'list');
function fn (data, index = '0-') {
return data.map((item, indexItem) => {
return {
value: `${index}${indexItem}`,
key: item.treeLevel,
treeName: item.treeName || item.name,
children: (() => {
if (item.capList && item.capList.length > 0) {
return fn(item.capList, `${index}${indexItem}-`);
} else {
return []
}
})()
}
})
}
console.log(fn(list));
处理后的数据
案列二如下:
需求分析:
据id和parentId把json数据结构转成树形状的数据结构
原数据
const temp = [
{
'id': 1,
'name': '1级1',
'parentId': 0
},
{
'id': 2,
'name': '2级1',
'parentId': 0
},
{
'id': 4,
'name': '1级1-1',
'parentId': 1
},
{
'id': 6,
'name': '1级1-1-1',
'parentId': 4
},
{
'id': 12,
'name': '2级1-1',
'parentId': 2
},
{
'id': 13,
'name': '3级1',
'parentId': 0
},
{
'id': 14,
'name': '3级1-1',
'parentId': 13
},
{
'id': 15,
'name': '1级1-1-1-1',
'parentId': 6
}
]
代码如下:
方法一:
const transData = (jsonArr, idStr, pidStr, childrenStr) => {
// 存放的最终结果树数组
const result = [];
const id = idStr;
const parentId = pidStr;
const children = childrenStr;
const len = jsonArr.length;
// 遍历得到以id为键名的对象(建立整棵树的索引)
const hash = {};
jsonArr.forEach(item => {
hash[item[id]] = item;
});
for (let j = 0; j < len; j++) {
const jsonArrItem = jsonArr[j];
const hashItem = hash[jsonArrItem[parentId]];
if (hashItem) {
// 如果当前项还没有children属性,则添加该属性并设置为空数组
!hashItem[children] && (hashItem[children] = []);
hashItem[children].push(jsonArrItem);
} else {
result.push(jsonArrItem);
}
}
return result;
};
const jsonDataTree = transData(temp, 'id', 'parentId', 'children');
console.log(jsonDataTree)
方法二:
// 调用方法, temp为原始数据, result为树形结构数据
var result = generateOptions(temp)
// 开始递归方法
generateOptions(params) {
var result = []
for (const param of params) {
if (param.parentId === 0) { // 判断是否为顶层节点
var parent = {
'id': param.id,
'label': param.name
}
parent.children = this.getchilds(param.id, params) // 获取子节点
result.push(parent)
}
}
return result
},
getchilds(id, array) {
const childs = []
for (const arr of array) { // 循环获取子节点
if (arr.parentId === id) {
childs.push({
'id': arr.id,
'label': arr.name
})
}
}
for (const child of childs) { // 获取子节点的子节点
const childscopy = this.getchilds(child.id, array)// 递归获取子节点
if (childscopy.length > 0) {
child.children = childscopy
}
}
return childs
}
对原有的树形结构添加新的字段值
原数据
const treeData = [{
name: '2021资源',
key: '1',
isLeaf: false,
children: [{
name: '服务器',
isLeaf: false,
key: '6',
children: [
{
isLeaf: false,
name: '172.168.201.109',
key: '5',
children: [
{
isLeaf: true,
children: [],
name: 'ping丢包率',
key: '2',
}, {
isLeaf: true,
children: [],
name: 'ping状态',
key: '3',
},
],
},
{
isLeaf: true,
children: [],
name: '192.168.3.6',
key: '7',
},
],
}],
}];
// 重新组合树数据(根据需要来重组树结构中的属性字段)
const dealTreeData = (treeData) => {
const data = treeData.map((item) => ({
...item,
// 新增title字段
title: item.name,
// 如果children为空数组,则置为null
children: (item.children && item.children.length)
? dealTreeData(item.children)
: null,
}));
return data;
};
console.log(JSON.stringify(dealTreeData(treeData)));
结果:
// 打印结果
// [{
// name: '2021资源',
// key: '1',
// isLeaf: false,
// title: '2021资源',
// children: [{
// name: '服务器',
// isLeaf: false,
// key: '6',
// title: '服务器',
// children: [{
// isLeaf: false,
// name: '172.168.201.109',
// key: '5',
// title: '172.168.201.109',
// children: [{
// isLeaf: true,
// children: null,
// name: 'ping丢包率',
// key: '2',
// title: 'ping丢包率',
// }, {
// isLeaf: true,
// children: null,
// name: 'ping状态',
// key: '3',
// title: 'ping状态',
// }],
// }, {
// isLeaf: true,
// children: null,
// name: '192.168.3.6',
// key: '7',
// title: '192.168.3.6',
// }],
// }],
// }];
(1),获取树中的所有祖先节点名称
const treeData = [{
key: '全部',
title: '全部',
isLeaf: false,
children: [{
key: '数据库',
title: '数据库',
isLeaf: false,
children: [
{
key: 'mysql',
title: 'mysql',
isLeaf: false,
children: [
{
key: '137',
title: 'QPS',
isLeaf: true,
}, {
key: '146',
title: 'MySQL进程信息',
isLeaf: true,
},
],
},
{
key: 'oracle',
title: 'oracle',
isLeaf: false,
children: [
{
key: '137',
title: 'QPS',
isLeaf: true,
},
],
},
],
}],
}];
// 获取树的所有祖先节点名称
const getTreeParents = (data) => {
const parentKey = [];
data.forEach((item) => {
if (item.children && item.children.length) {
parentKey.push(item.key);
const temp = getTreeParents(item.children);
if (temp.length) {
parentKey.push(...temp);
}
}
});
return parentKey;
};
const parentKeys = getTreeParents(treeData);
console.log(parentKeys); // ["全部", "数据库", "mysql", "oracle"]
(2),获取树中叶子节点的总个数(节点中isLeaf为true的节点)
const treeData = {
name: '2021资源',
title: '2021资源',
key: '1',
isLeaf: false,
children: [{
name: '服务器',
isLeaf: false,
title: '服务器',
key: '6',
children: [
{
name: '172.168.201.109',
isLeaf: false,
title: '172.168.201.109',
key: '5',
children: [
{
name: 'ping丢包率',
isLeaf: true,
children: null,
title: 'ping丢包率',
key: '2',
}, {
name: 'ping状态',
isLeaf: true,
children: null,
title: 'ping状态',
key: '3',
},
],
},
{
name: '192.168.3.6',
isLeaf: true,
children: null,
title: '192.168.3.6',
key: '7',
},
],
}],
};
const getLeafNum = (treeNode) => {
let leafNum = 0;
if (!treeNode) {
return leafNum;
}
if (treeNode.children && treeNode.children.length) {
treeNode.children.forEach((item) => {
leafNum += getLeafNum(item);
});
} else {
if (treeNode.isLeaf) {
leafNum++;
}
}
return leafNum;
};
console.log(getLeafNum(treeData)); // 3
(3),根据过滤条件筛选出需要留下节点的树结构数据(般用于前端做树的查询功能。)
/**
* 递归过滤节点,但保留原树结构,即符合条件节点的父路径上所有节点不管是否符合条件都保留
* @param {Node[]} nodes 要过滤的树
* @param {node => boolean} predicate 过滤条件,符合条件的节点保留(参数为函数,返回值为布尔值)
* @param {node => boolean} wrapMatchFn 层级条件(参数为函数,返回值为布尔值)
* @return 过滤后的包含根节点数组
*/
export const filterSearchTree = (nodes, predicate, wrapMatchFn = () => false) => {
// 如果已经没有节点了,结束递归
if (!(nodes && nodes.length)) {
return []
}
const newChildren = []
for (let i = 0; i < nodes.length; i++) {
const node = nodes[i]
// 想要截止匹配的那一层(如果有匹配的则不用递归了,直接取下面所有的子节点)
if (wrapMatchFn(node) && predicate(node)) {
newChildren.push(node)
continue
}
const subs = filterSearchTree(node.children, predicate, wrapMatchFn)
// 以下两个条件任何一个成立,当前节点都应该加入到新子节点集中
// 1. 子孙节点中存在符合条件的,即 subs 数组中有值
// 2. 自己本身符合条件
if ((subs && subs.length) || predicate(node)) {
node.children = subs || []
newChildren.push(node)
}
}
return newChildren.length ? newChildren : []
}
const treeData = [{
key: '全部',
title: '全部',
isLeaf: false,
children: [{
key: '数据库',
title: '数据库',
isLeaf: false,
children: [
{
key: 'mysql',
title: 'mysql',
isLeaf: false,
children: [
{
key: '142',
title: '慢查询',
isLeaf: true,
}, {
key: '137',
title: 'QPS',
isLeaf: true,
}, {
key: '143',
title: '用户列表',
isLeaf: true,
},
],
},
{
key: '166',
title: 'SQL',
isLeaf: true,
},
],
}],
}];
// 要查找的关键字
const searchValue = 'S';
// 筛选到的树结构数据
const newTreeData = filterSearchTree(
treeData,
(node) => {
if (node.title.indexOf(searchValue) !== -1) {
return true;
}
return false;
},
);
// const newTreeData = filterSearchTree(
// cloneTreeDatas,
// (node) => {
// if (node.title.includes(searchValue)) {
// return true
// }
// return false
// },
// (node) => {
// // 第二层(显示左侧角色组数据)
// if (node.groupName) {
// return true
// }
// return false
// }
// )
console.log(JSON.stringify(newTreeData));
// 打印的结果
// [{
// key: '全部',
// title: '全部',
// isLeaf: false,
// children: [{
// key: '数据库',
// title: '数据库',
// isLeaf: false,
// children: [{
// key: 'mysql',
// title: 'mysql',
// isLeaf: false,
// children: [{
// key: '137',
// title: 'QPS',
// isLeaf: true,
// children: null,
// }],
// }, {
// key: '166',
// title: 'SQL',
// isLeaf: true,
// children: null,
// }],
// }],
// }];