Tree structure data search and filter method
/**
* 检索找到所有符合条件的节点,保留树结构
* @param { Array | Object } data 树状结构数据
* @param { String } childrenKey 子节点key值
* @param { Function } expresion 条件函数,判断节点是否符合条件,返回bool类型
*/
export function recursionTree(data, childrenKey, expresion) {
if (Array.isArray(data)) {
let result = [];
data.forEach(item => {
let itemResult = recursionTree(item, childrenKey, expresion);
if (itemResult) {
result.push(itemResult);
}
});
return result.length > 0 ? result : null;
} else {
if (expresion(data)) {
if (data[childrenKey]) {
data[childrenKey] = recursionTree(data[childrenKey], childrenKey, expresion);
}
return data;
} else {
if (data[childrenKey]) {
data[childrenKey] = recursionTree(data[childrenKey], childrenKey, expresion);
return data[childrenKey] && data[childrenKey].length > 0 ? data : null;
} else {
return null;
}
}
}
}
/**
* 检索找到所有符合条件的节点,返回数组
* @param { Array | Object } data 树状结构数据
* @param { String } childrenKey 子节点key值
* @param { Function } expresion 条件函数,判断节点是否符合条件,返回bool类型
*/
export function recursionAll(data, childrenKey, expresion) {
let result = [];
if (Array.isArray(data)) {
data.forEach(item => {
let itemResult = recursionAll(item, childrenKey, expresion);
if (itemResult) {
result = result.concat(itemResult);
}
});
} else if (expresion(data)) {
result.push(data);
}
if (data[childrenKey] && Array.isArray(data[childrenKey])) {
data[childrenKey].forEach(item => {
let itemResult = recursionAll(item, childrenKey, expresion);
if (itemResult) {
result = result.concat(itemResult);
}
});
}
return result;
}
/**
* 平铺数组数据转换成tree结构的数据, 只支持两层树结构
* @param { Array } data 平铺数组数据
* @param { String } idKey 数据唯一标识
* @param { String } ParentKey 标识父节点的key值
* @param { String } childrenKey 构建的子节点key值
*/
export function structTreeData(data, idKey, parentKey, childrenKey) {
let result = JSON.parse(JSON.stringify(data));
for (let i = result.length -1; i >= 0; i--) {
let current = result[i];
// 寻找当前数据的父节点
let index = result.findIndex(item => item[idKey] === current[parentKey]);
if (index >= 0) {
result[index][childrenKey] = result[index][childrenKey] || [];
// 把当前节点塞到父节点的childrenKey中
result[index][childrenKey].push(current);
// 从result中删除当前数据
result.splice(i, 1);
}
}
return result;
}
use
<template>
<div>树结构数据处理</div>
</template>
<script>
import { recursionTree, recursionAll, structTreeData } from '../../utils/recursion';
export default {
name: 'home',
data() {
return {
treeData: [
{ id: 1, name: 'Home', parentId: 0, visible: true },
{ id: 2, name: 'System', parentId: 0, visible: true, children: [
{ id: 21, name: 'User', parentId: 2, visible: true },
{ id: 22, name: 'Role', parentId: 2, visible: true },
{ id: 23, name: 'Menu', parentId: 2, visible: false },
{ id: 24, name: 'File', parentId: 2, visible: true },
]},
{ id: 3, name: 'Monitor', parentId: 0, visible: true, children: [
{ id: 31, name: 'Online', parentId: 3, visible: true },
{ id: 32, name: 'Statistics', parentId: 3, visible: true, children: [
{ id: 321, name: 'UserStatistics', parentId: 32, visible: false },
{ id: 322, name: 'RoleStatistics', parentId: 32, visible: true },
] },
]},
],
arrayData: [
{ id: 1, name: 'Home', parentId: 0, visible: true },
{ id: 2, name: 'System', parentId: 0, visible: true },
{ id: 21, name: 'User', parentId: 2, visible: true },
{ id: 22, name: 'Role', parentId: 2, visible: true },
{ id: 23, name: 'Menu', parentId: 2, visible: false },
{ id: 24, name: 'File', parentId: 2, visible: true },
{ id: 3, name: 'Monitor', parentId: 0, visible: true },
{ id: 31, name: 'Online', parentId: 3, visible: true },
{ id: 32, name: 'Statistics', parentId: 3, visible: true },
],
};
},
created() {
// 查找visible为false的数据,保留树结构
const data1 = recursionTree(this.treeData, 'children', item => !item.visible);
console.log('data1', data1);
// 查找visible为false的值,返回数组
const data2 = recursionAll(this.treeData, 'children', item => !item.visible);
console.log('data2', data2);
// 父子数组数据转换成树结构
const data3 = structTreeData(this.arrayData, 'id', 'parentId', 'children');
console.log('data3', data3);
}
}
</script>
<style scoped>
</style>