React Tree树形结构封装工具类

需要依赖 immutable,用于group by分组

buildTree 为入口方法,注意返回的是Immutable.List对象,使用需要调用.toJS()方法转为普通对象

其中 creatNode方法为构建节点对象,可根据自己需求动态修改该方法

import Immutable, { List, Map } from "immutable";

/**
 *构建树
 * @param dataList 数据源,array/Immutable.List
 * @param arg 参数,可选
 * @param arg.rootCode 根节点,默认为#
 * @param arg.parentField 关联父节点key字段 默认为parent
 * @param arg.keyField 当前节点key字段,默认为id
 * @param arg.iconRender 图标渲染 func(item,arg)
 * @param arg.keyRender func key渲染 func(item,arg) //当需要key做处理时使用,默认为keyField字段值,一般不使用
 * @param arg.textRender 文字渲染 func(item,arg) 默认取text字段
 * @param arg.checkableRender 复选框显示 func(item,arg) 当树为checkable时使用 默认为true
 * @returns {Immutable.List<*>}
 */
export const buildTree = (dataList = List([]), arg) => {
  if (!(dataList instanceof List)) {
    dataList = Immutable.fromJS(dataList)
  }
  const config = {
    rootCode: "#",
    parentField: "parent",
    keyField: "id",
    iconRender: undefined,
    keyRender: (nodeInfo, arg) => {
      return nodeInfo.get(arg.keyField)
    },
    textRender: (nodeInfo, arg) => {
      return nodeInfo.get("text")
    },
    checkableRender: (nodeInfo, arg) => {
      return true
    },
    ...arg
  }
  let treeData = List([])
  if (dataList.size === 0) {
    return treeData
  }
  const groupTree = dataList.groupBy(nodeInfo => nodeInfo.get(config.parentField))
  if (groupTree && groupTree.size > 0) {
    let collection = groupTree.get(config.rootCode);
    if (collection && collection.size > 0) {
      collection.forEach(role => {
        let node = creatNode(role, config)
        let list = buildChildren(node, role, groupTree, config);
        if (list && list.size > 0) {
          node = node.set("children", list)
        }
        treeData = treeData.push(node)
      })
    }
  }
  return treeData
}
//构建子树
const buildChildren = (newParent, oldParent, groupTree = Map({}), config) => {
  let childList = groupTree.get(oldParent.get(config.keyField));
  let children = List([]);
  if (childList && childList.size > 0) {
    childList.forEach(role => {
      let node = creatNode(role, config)
      let list = buildChildren(node, role, groupTree, config);
      if (list && list.size > 0) {
        node = node.set("children", list)
      }
      children = children.push(node)
    })
  }
  return children
}
//创建节点,可扩充属性
const creatNode = (nodeInfo, config) => {
  let node = {
    key: config.keyRender(nodeInfo, config),
    title: config.textRender(nodeInfo, config)
  }
  if (config.iconRender) {
    node.icon = config.iconRender(nodeInfo, config)
  }
  if (config.checkableRender) {
    node.checkable = config.checkableRender(nodeInfo, config)
  }
  return Map(node)
}
posted @ 2023-01-16 15:58  雪月风殇  阅读(216)  评论(0编辑  收藏  举报