难点:展示可选异步树本不难,就是难以在选中父节点时,获取其下所有子节点的数据。
注意:结合antd官网的属性理解
1、节点代码
this.state = {
//自动展开父节点
autoExpandParent:true,
check:[],
//异步加载的keys
loadedKeys:[],
//树节点数据
treeData:[],
}
return (
<Tree
checkable
checkedKeys={check}
autoExpandParent={autoExpandParent}
onCheck={this.handleCheck}
loadData-{this.onLoadData}
loadedKeys={loadedeys}
onLoad={this.onLoad}
>
{this.loop(this.state,treeData)}
</Tree>
)
2、获取异步树数据源
//获取异步树数据
getResourceTree = node =>{
const params={code:node.code}
return new Promise(resolve => {
getAsyncResourceTree(params).then(res => {
const result={
isSuccess:res?.isSuccess || false,
data:res?.data || []
}
resolve(result);
});
});
};
//加载时调用
onLoadData = treeNode =>
new Promise(async resove => {
//已经加载过孩子节点,就不加载了
if(treeNode.props.child){
resolve();
retuen;
}
const res = await this.getResourceTree(treeNode.props.dataRef);
//延时效果,让用户知道是异步
setTimeout(() => {
treeNode.props.dataRef.child = res?.data;
this.setState({
treeData:[...this.state.treeData]
});
resolve();
},1000);
});
//加载后的回调
onLoad = loadedKeys => {
this.setState({ loadKeys })
}
3、渲染异步树节点
loopNodes = (data,value) =>
data.map(item => {
//有子节点就递归,没有就渲染成叶子节点
if(item.child){
return (
<TreeNode
key = {item.code}
title={title}
dataRef = {item}
>
{this.loopNodes(item.child)}
</TreeNode>
)
}
return (
<TreeNode
key={item.code}
title={title}
dataRef={item}
isLeaf={item.child_num === 0}
/>
)
})
以上已完成异步树的展示
要想在选择父节点时,自动加载其下所有子节点,看下面
4、选中节点时,获取其下所有子节点的数据
//选中节点时触发的回调
handleCheck = (data,e) => {
const laste = e;
this.finChildNodes(data,e,laste);
}
//加载选中节点下的所有子节点
findChildNodes = (data,e,laste) => {
Promise.all(
e?.checkedNodes?.map(async item => {
const res = await this.getResourceTree(item.props.dataRef);
//根据id去重,然后赋值
const idList = laste.checkNodes.map(i=> i.props.dataRef.id);
const filterRes = res.data.filter(val => !idList.includes(val.id));
laste.checkedNodes.push(
...filters.map(i => {
return {props : { dataRef: i }}
})
);
res.data?foreach(node => {
//如果有子节点,就继续递归加载
if(node.child_num > 0){
const Res = {
checkedNodes: res.data.map(i => {
return { props: {dataRef : i }}
}),
};
this.findChildNodes(data,Res,laste);
}
});
})
).then(()=>{
//可在此处拿到最终的所有节点数据
console.log(laste)
})
}