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)
   })
}

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
为了方便在 React 项目中使用 Ant Design 的 Loading 组件,可以封装一个 Loading 工具类,以便在需要时快速调用。 以下是一个基于 Ant Design 的 Loading 工具类的示例: ```jsx import { Spin } from 'antd'; // 加载中组件 const Loading = () => ( <div style={{ textAlign: 'center', marginTop: 50 }}> <Spin size="large" /> </div> ); // Loading 工具类 class LoadingUtil { static loadingInstance = null; static create() { if (!LoadingUtil.loadingInstance) { LoadingUtil.loadingInstance = Spin; } return LoadingUtil.loadingInstance; } static show() { const LoadingComponent = LoadingUtil.create(); LoadingUtil.loadingInstance = LoadingComponent; LoadingComponent.show(); } static hide() { const LoadingComponent = LoadingUtil.create(); LoadingUtil.loadingInstance = LoadingComponent; LoadingComponent.hide(); } } export default LoadingUtil; ``` 在上面的代码中,首先定义了一个 Loading 组件,它是 Ant Design Spin 组件的包装,用于显示加载中的效果。 然后定义了一个 LoadingUtil 类,它包含了三个静态方法: - `create()` 方法用于创建 Loading 组件实例; - `show()` 方法用于显示 Loading 组件; - `hide()` 方法用于隐藏 Loading 组件。 当需要显示 Loading 时,调用 `LoadingUtil.show()` 方法即可;当需要隐藏 Loading 时,调用 `LoadingUtil.hide()` 方法即可。 使用该 Loading 工具类的示例如下: ```jsx import React, { useState } from 'react'; import LoadingUtil from './LoadingUtil'; function MyComponent() { const [loading, setLoading] = useState(false); const handleButtonClick = () => { setLoading(true); LoadingUtil.show(); // 异步操作 setTimeout(() => { setLoading(false); LoadingUtil.hide(); }, 2000); }; return ( <div> <h1>My Component</h1> <button onClick={handleButtonClick}>Fetch Data</button> {loading && <Loading />} </div> ); } export default MyComponent; ``` 在上面的代码中,当用户点击按钮触发异步操作时,设置 `loading` 状态为 `true`,同时调用 `LoadingUtil.show()` 方法显示 Loading 组件。 当异步操作完成后,设置 `loading` 状态为 `false`,同时调用 `LoadingUtil.hide()` 方法隐藏 Loading 组件。最后在 JSX 中根据 `loading` 状态来决定是否渲染 Loading 组件。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值