1
[{
  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
})

爱吃鸡蛋饼
55 声望8 粉丝