前端树型操作的常用方法

89 阅读1分钟

列表转树结构

const listToTreeFn = (list) => {
  let obj = list.reduce(
    (map, node) => ((map[node.id] = node), (node.children = []), map),
    {}
  );
  return list.filter((node) => {
    obj[node.pid] && obj[node.pid].children.push(node);
    // 根节点没有pid,可当成过滤条件
    return !node.pid;
  });
};

查找节点

const treeFindFn = (tree, func) => {
  for (let node of tree) {
    if (func(node)) return node;
    if (node.children) {
      let result = treeFindFn(node.children, func);
      if (result) return result;
    }
  }
  return false;
};

// 示例
let findFlag1 = treeFindFn(provinceList, (node) => node.id === "XXX");

选中节点禁用等类似操作操作

const disabledTreeFn = (tree, targetKeys) => {
  tree.forEach((o) => {
    let flag = targetKeys.includes(o.id);
    o["key"] = o.id;
    o["title"] = o.label; // 这里也可以做些显示操作等
    o["disabled"] = flag;
    o.children && disabledTreeFn(o.children, targetKeys);
  });
  return tree;
};

获取某个节点的所有父级节点

方法一:
const treeFindPathFn = (tree, func, path = []) => {
  if (!tree) return [];

  for (let node of tree) {
    path.push(node.id);
    if (func(node)) return path;
    if (node.children) {
      const findChild = treeFindPathFn(node.children, func, path);
      if (findChild.length) return findChild;
    }
    path.pop();
  }
  return [];
};

// 测试代码
let findPathFlag = treeFindPathFn(
  provinceList,
  (node) => node.id === "100102"
);

方法二:
const getAllParents = (list,node,key, childKey) => {
  for (let i in list) {
    if(list[i][key] != undefined && list[i][key] == node[key]){
      return [list[i]]
    }
    if(list[i][childKey]){
      let _node= getAllParents(list[i][childKey], node, key, childKey);
      if(_node!==undefined){
        return _node.concat(list[i])
      }
    }
  }
}

后续若有新增会继续补充。。。