[{
id: 1,
title: 节点1,
parentId: null
},
{
id: 2,
title: 节点2,
parentId: 1
},
{
id: 3,
title: 节点3,
parentId: null
},
{
id: 4,
title: 节点4,
parentId: 2
},
{
id: 5,
title: 节点5,
parentId: 3
}]
形如以上常见后端返回的数据结构。可用以下方法构成树:
getParentData(data) {
let cloneData = JSON.parse(JSON.stringify(data));
let parentData = [];
for (let parent of cloneData) {
if (parent.parentId === null || parent.parentId === "") {
parent.label = parent.title;
parent.value = parent.id;
let childrenCopy = this.getChildren(parent.id, cloneData);
if (childrenCopy.length > 0) {
parent.children = childrenCopy;
}
parentData.push(parent);
}
}
return parentData;
},
getChildren(parentId, data) {
let children = [];
for (let child of data) {
if (child.parentId === parentId) {
child.label = child.title;
child.value = child.id;
children.push(child);
}
}
for (let child of children) {
let childrenCopy = this.getChildren(child.id, data);
if (childrenCopy.length > 0) {
child.children = childrenCopy;
}
}
return children;
}
另外,如果需要对某节点后数据做禁用操作。可传入其ID值进行筛选。代码如下:
getParentData(data, id){
let cloneData = JSON.parse(JSON.stringify(data));
let parentData = [];
for(let parent of cloneData){
if(parent.parentId === null || parent.parentId === ""){
parent.label = parent.title;
parent.value = parent.id;
if(parent.id === id){
parent.disabled = true;
}
else{
parent.disabled = false;
}
let childrenCopy = this.getChildren(parent.id, cloneData, id, parent.disabled);
if(childrenCopy.length > 0){
parent.children = childrenCopy;
}
parentData.push(parent);
}
}
return parentData;
},
getChildren(parentId, data, id, isDisable){
let children = [];
for(let child of data){
if(child.parentId === parentId){
child.label = child.title;
child.value = child.id;
if(isDisable){
child.disabled = true;
}
else{
if(child.id === id){
child.disabled = true;
}
else{
child.disabled = false;
}
}
children.push(child);
}
}
for(let child of children){
let childrenCopy = this.getChildren(child.id, data, id, child.isDisable);
if(childrenCopy.length > 0){
child.children = childrenCopy;
}
}
return children;
}
针对某个id,寻找该ID在树的路径,可用以下方法遍历寻找:
getTreePath(tree, id) {
let path = [];
function dfs(tree) {
for (let i = 0; i < tree.length; i++) {
if (tree[i].value === id) {
path.unshift(tree[i].value);
return true;
} else if (tree[i].children) {
if (dfs(tree[i].children)) {
path.unshift(tree[i].value);
return true;
}
}
}
}
dfs(tree);
return path;
}
再举个递归查找节点的例子:
const tree = [
{
id: 01,
pid: null,
children: [
{
id: 03,
pid: 01,
children: [
{ id: 04, pid: 03 },
{ id: 06, pid: 03 },
]
},
{ id: 05, pid: 01 },
]
},
{
id: 02,
pid: null,
children: [
{
id: 07,
pid: 02,
children: [
{ id: 10, pid: 07 },
{ id: 11, pid: 07 },
]
},
{ id: 09, pid: 02 },
]
},
]
function findCurNode(tree, curKey, keyField) {
tree.forEach((item) => {
if (item[keyField] === curKey) {
return item
}
if (item.children && item.children.length) {
const node = findCurNode(item.children, curKey, keyField)
if (node) {
return node
}
}
})
}
let a = findCurNode(tree, 10, 'id');console.log(a)
或者这样:
findNode(tree, func) {
for (const node of tree) {
if (func(node)) return node
if (node.children) {
const res = this.findNode(node.children, func)
if (res) return res
}
}
return null
}
this.findNode(res.data, (node) => {
return node.id === this.id
})
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。