react基于antd的Tree封装的可选异步树

难点:展示可选异步树本不难,就是难以在选中父节点时,获取其下所有子节点的数据。

注意:结合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)
   })
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值