在使用element ui的tree组建的时候经常需要对tree进行递归操作,去获取树形数据中的某些值,下面总结了常用的一些方法
根据树形数据找出节点id为指定值的节点
function findNodeById(treeData, nodeId) {
// 遍历当前层级的所有节点
for (var i = 0; i < treeData.length; i++) {
var node = treeData[i];
// 如果当前节点的 ID 匹配目标节点的 ID,则返回当前节点
if (node.id === nodeId) {
return node;
}
// 如果当前节点有子节点,则递归调用当前函数继续查找子节点
if (node.children && node.children.length > 0) {
var foundNode = findNodeById(node.children, nodeId);
// 如果在子节点中找到了目标节点,则返回找到的节点
if (foundNode) {
return foundNode;
}
}
}
// 如果遍历完所有节点仍未找到目标节点,则返回 null
return null;
}
// 如果遍历完所有子节点仍未找到目标节点,则返回 null
return null;
}
根据根节点的id将一个一维数组转变为树形数据
rootValue即根节点的id
function transListToTreeData(list, rootValue) {
// 思路:先找到所有的根节点,然后再再去添加children,第二个参数是根节点的pid值
var arr = [];
list.forEach((item) => {
if (item.pid === rootValue) {
const children = transListToTreeData(list, item.id);
if (children.length) {
// 如果children的长度大于0就说明找到了子节点
item.children = children;
}
arr.push(item);
}
});
return arr;
}
获取树形根节点的status 值为currentStatus的根节点的节点个数
function getRootNodeByStatusCount(treeData,currentStatus){
let count = 0;
if (treeData && treeData.length) {
// 判断数据是否存在并且不为空
for (let i = 0; i < treeData.length; i++) {
// 遍历子节点
const node = treeData[i];
if (node.status == currentStatus) {
// 如果当前节点的 status 为 0,count 加一
count++;
}
if (node.children && node.children.length > 0) {
// 如果当前节点存在子节点,则递归遍历子节点
count += getRootNodeByStatusCount(node.children,currentStatus);
}
}
}
return count;
},
获取根节点的个数
function getRootNodeCount(treeData) {
if (!Array.isArray(treeData)) {
return 0;
}
let count = 0;
for (const node of treeData) {
// 如果当前节点没有子节点,则累加计数器
if (!node.children) {
count++;
}
if (Array.isArray(node.children)) {
// 如果节点有子节点,对其进行递归处理
count += this.getRootNodeCount(node.children);
}
}
return count;
},
根据传入的id数组,给该节点添加一个disabled属性值为false,其他节点添加一个disabled属性值为true
function disableTreeNodes(treeData, idArray) {
if (!Array.isArray(treeData)) {
return;
}
for (const node of treeData) {
if (idArray.includes(node.id)) {
// 如果当前节点在 idArray 数组中,则继续递归它的子节点
// if (Array.isArray(node.children)) {
node.disabled = false;
disableTreeNodes(node.children, idArray);
// }
} else {
// 否则将当前节点设为禁用状态,并递归它的子节点
node.disabled = true;
if (Array.isArray(node.children)) {
disableTreeNodes(node.children, idArray);
}
}
}
},
返回根节点status属性值为status的节点树
function filterRootNodes(data,status) {
if (!data || data.length === 0) {
// 判断数据是否存在并且不为空,如果是,则直接返回空数组
return [];
}
const filteredData = []; // 定义过滤后的数据数组
for (let i = 0; i < data.length; i++) {
// 遍历每个节点
const node = data[i];
if (node.status == status) {
filteredData.push(node);
}
if (node.children && node.children.length > 0) {
// 如果当前节点存在子节点,则递归遍历子节点
const filteredChildren = filterRootNodes(node.children,status); // 对子节点进行递归过滤
if (filteredChildren.length > 0) {
// 如果过滤后的子节点不为空,则将该节点加入到过滤后的数据数组中,并将过滤后的子节点作为其 children 属性的值
filteredData.push({
name: node.name,
id:node.id,
children: filteredChildren,
});
}
}
}
return filteredData;
},
测试数据:
[{
label: '一级 1',
children: [{
label: '二级 1-1',
children: [{
label: '三级 1-1-1',
status:1,
}]
}]
}, {
label: '一级 2',
children: [{
label: '二级 2-1',
children: [{
label: '三级 2-1-1',
status:1,
}]
}, {
label: '二级 2-2',
children: [{
label: '三级 2-2-1',
status:0,
}]
}]
}, {
label: '一级 3',
children: [{
label: '二级 3-1',
children: [{
label: '三级 3-1-1',
status:1,
}]
}, {
label: '二级 3-2',
children: [{
label: '三级 3-2-1',
status:0,
}]
}]
}]
返回数据:
[{
label: '一级 1',
children: [{
label: '二级 1-1',
children: [{
label: '三级 1-1-1',
status:1,
}]
}]
}, {
label: '一级 2',
children: [{
label: '二级 2-1',
children: [{
label: '三级 2-1-1',
status:1,
}]
}]
}, {
label: '一级 3',
children: [{
label: '二级 3-1',
children: [{
label: '三级 3-1-1',
status:1,
}]
}]
}]