zarm-web
Version:
基于 React 的桌面端UI库
211 lines (191 loc) • 5.26 kB
JavaScript
import React, { Component } from 'react';
import TreeNode from './TreeNode';
import { getTreeNodeChildren, convertTreeToData, initialTreeData, conductExpandParent, conductCheck, arrDel, arrAdd, deepCopy } from './utils';
class Tree extends Component {
constructor(...args) {
super(...args);
this.state = {
checkedKeys: [],
halfCheckedKeys: [],
expandedKeys: [],
treeData: []
};
this.initTreeNodes = () => {
const {
treeData = [],
checkedKeys,
expandedKeys,
defaultExpandAll,
children
} = this.props;
const newState = {
treeData: [],
halfCheckedKeys: [],
checkedKeys: [],
expandedKeys: []
};
let TreeDataInformationSet = {
allExpandDataMap: {},
treeData: []
};
if (treeData.length > 0) {
// 深拷贝treeData
newState.treeData = deepCopy(treeData);
TreeDataInformationSet = initialTreeData(newState.treeData);
} else if (children) {
const treeNodeChildren = getTreeNodeChildren({
children
});
if (treeNodeChildren.length > 0) {
TreeDataInformationSet = initialTreeData(convertTreeToData(treeNodeChildren));
}
}
const {
allExpandDataMap,
treeData: initialedTreeData
} = TreeDataInformationSet;
newState.treeData = initialedTreeData; // 初始化checkedKeys,更新treeData
if (checkedKeys && checkedKeys.length > 0) {
const {
checkedKeys: finalCheckedKeys,
halfCheckedKeys: finalHalfCheckedKeys,
treeData: finaltreeDataAfter
} = conductCheck(checkedKeys, true, newState.treeData);
newState.checkedKeys = finalCheckedKeys;
newState.halfCheckedKeys = finalHalfCheckedKeys;
newState.treeData = finaltreeDataAfter;
}
/*
初始化expandedKeys
如果要展开所有结点,则取到所有根结点作为展开结点;
否则展开传入的展开结点
*/
if (defaultExpandAll) {
newState.expandedKeys = conductExpandParent(Object.keys(allExpandDataMap), newState.treeData);
} else if (expandedKeys && expandedKeys.length > 0) {
newState.expandedKeys = conductExpandParent(expandedKeys, newState.treeData);
}
this.setState(newState);
};
this.onNodeCheck = (node, targetChecked, event) => {
const {
onCheck
} = this.props;
const {
keys
} = node.props;
const {
treeData: originalTreeData
} = this.state;
const {
checkedKeys: originalCheckedKeys,
halfCheckedKeys: originHalfCheckedKeys
} = this.state;
const {
checkedKeys,
halfCheckedKeys,
treeData
} = conductCheck([keys], targetChecked, originalTreeData, {
checkedKeys: originalCheckedKeys,
halfCheckedKeys: originHalfCheckedKeys
});
const checkedMap = {
checkedKeys,
halfCheckedKeys
};
this.setState({
checkedKeys,
halfCheckedKeys,
treeData
});
if (onCheck) {
onCheck(checkedMap, {
node,
checked: targetChecked,
event
});
}
};
this.onNodeExpand = (node, targetExpanded, event) => {
let {
expandedKeys
} = this.state;
const {
onExpand
} = this.props;
const {
keys
} = node.props;
if (targetExpanded) {
expandedKeys = arrAdd(expandedKeys, keys);
} else {
expandedKeys = arrDel(expandedKeys, keys);
}
this.setState({
expandedKeys
});
if (onExpand) {
onExpand({
expandedKeys,
node,
expanded: targetExpanded,
event
});
}
};
this.renderTreeNodes = data => {
const {
prefixCls,
canCheck
} = this.props;
const {
expandedKeys,
checkedKeys,
halfCheckedKeys
} = this.state;
return data.map((item, index) => {
const {
keys,
title,
checkDisabled,
children
} = item;
return React.createElement(TreeNode, {
key: `${index}`,
keys: keys,
title: title,
canCheck: canCheck,
checkDisabled: !!checkDisabled,
prefixCls: prefixCls,
expanded: expandedKeys.indexOf(keys) !== -1,
checked: checkedKeys.indexOf(keys) !== -1,
halfChecked: halfCheckedKeys.indexOf(keys) !== -1,
isLeaf: !children,
onNodeCheck: this.onNodeCheck,
onNodeExpand: this.onNodeExpand
}, children ? this.renderTreeNodes(children) : null);
});
};
}
componentWillMount() {
this.initTreeNodes();
}
render() {
const {
prefixCls
} = this.props;
const {
treeData
} = this.state;
return React.createElement("ul", {
className: prefixCls
}, this.renderTreeNodes(treeData));
}
}
Tree.defaultProps = {
prefixCls: 'ui-tree',
checkedKeys: [],
expandedKeys: []
};
Tree.TreeNode = void 0;
export default Tree;