Ant Design中Tree组件使用(包括异步加载子节点)

普通加载: 

import React, { Component } from 'react'
import { Tree } from 'antd'

const { DirectoryTree } = Tree;

export default class tree extends Component {
    state = {

    }

    /**
     * 树
     */
    getTreeData = () => {
        return [
            {
                title: '机构一',
                key: '0-0',
                children: [
                    {
                        title: '用户一',
                        key: '0-0-0',
                        isLeaf: true,
                    },
                    {
                        title: '用户二',
                        key: '0-0-1',
                        isLeaf: true,
                    },
                    {
                        title: '用户三',
                        key: '0-0-2',
                        isLeaf: true,
                    },
                    {
                        title: '用户四',
                        key: '0-0-3',
                        isLeaf: true,
                    },
                    {
                        title: '用户五',
                        key: '0-0-4',
                        isLeaf: true,
                    },
                    {
                        title: '用户六',
                        key: '0-0-5',
                        isLeaf: true,
                    },
                ],
            },
            {
                title: '机构二',
                key: '0-1',
                children: [
                    {
                        title: '用户七',
                        key: '0-1-0',
                        isLeaf: true,
                    },
                    {
                        title: '用户八',
                        key: '0-1-1',
                        isLeaf: true,
                    },
                    {
                        title: '用户九',
                        key: '0-1-2',
                        isLeaf: true,
                    },
                    {
                        title: '用户十',
                        key: '0-1-3',
                        isLeaf: true,
                    },
                ],
            },
        ];
    }

    onSelect = (selectedKeys, info) => {
        console.log('selected', selectedKeys, info);
    };

    onCheck = (checkedKeys, info) => {
        console.log('onCheck', checkedKeys, info);
    };

    componentWillMount() {
        this.treeData = this.getTreeData();
    }

    render() {
        return (
            <div>
                <DirectoryTree
                    defaultExpandedKeys={['0-0-0', '0-0-1']}
                    defaultSelectedKeys={['0-0-0', '0-0-1']}
                    defaultCheckedKeys={['0-0-0', '0-0-1']}
                    onSelect={this.onSelect}
                    onCheck={this.onCheck}
                    treeData={this.treeData}
                />
            </div>
        )
    }
}

异步加载: 

// 父组件 App.js
import logo from './logo.svg';
import './App.css';
import As from "./AsTree.js"

function App() {
  const onCheckTree = (value) => {
    console.log(value, '点击了')
  }

  return (
    <div className="App">
      <As clickTree={onCheckTree} baseApi={"https://xxx.xxx.cn"} token={"L6qbt0KutJyV0L8I_R6Mw7yYueNmSLCFLWx1Duqf3zQ.BdmQm8Kry1mobxOlGCgFt7mQsyRwiVPHO21aLJdM3hk"} />
    </div>
  );
}

export default App;

// 子组件 AsTree.js
import {
    Tree
  } from 'antd';
  import React, {
    useState,
    useEffect
  } from 'react';
  import { DownOutlined } from '@ant-design/icons';
  import './App.css';
  
  const updateTreeData = (list, key, children) =>
    list.map((node) => {
      if (node.key === key) {
        return {
          ...node,
          children
        };
      }
  
      if (node.children) {
        return {
          ...node,
          children: updateTreeData(node.children, key, children)
        };
      }
  
      return node;
    });
  
  const App = (props) => {
    const [treeData, setTreeData] = useState([]);
  
    useEffect(() => {
      fetch(`${props.baseApi}/api/efast/v1/entry-doc-lib`, {
        method: "GET",
        headers: {
          'authorization': "Bearer " + props.token
        }
      }).then((response) => response.json()).then(resJson => {
        const typeArr = [];
        const user_doc_lib = [];
        const department_doc_lib = [];
        const custom_doc_lib = [];
        const shared_user_doc_lib = [];
        const knowledge_doc_lib = [];
  
        for (let i = 0; i < resJson.length; i++) {
          if (typeArr.indexOf(resJson[i].type) < 0) {
            typeArr.push(resJson[i].type);
          }
  
          if (resJson[i].type === "user_doc_lib") {
            user_doc_lib.push({
              key: resJson[i]["id"],
              title: resJson[i]["name"],
              isLeaf: false
            });
          } else if (resJson[i].type === "department_doc_lib") {
            department_doc_lib.push({
              key: resJson[i]["id"],
              title: resJson[i]["name"],
              isLeaf: false
            });
          } else if (resJson[i].type === "custom_doc_lib") {
            custom_doc_lib.push({
              key: resJson[i]["id"],
              title: resJson[i]["name"],
              isLeaf: false
            });
          } else if (resJson[i].type === "shared_user_doc_lib") {
            shared_user_doc_lib.push({
              key: resJson[i]["id"],
              title: resJson[i]["name"],
              isLeaf: false
            });
          } else if (resJson[i].type === "knowledge_doc_lib") {
            knowledge_doc_lib.push({
              key: resJson[i]["id"],
              title: resJson[i]["name"],
              isLeaf: false
            });
          }
        }
  
        for (let i = 0; i < typeArr.length; i++) {
          if (typeArr[i] == "user_doc_lib") {
            typeArr[i] = {
              key: 0,
              title: "个人文档库",
              isLeaf: false,
              children: user_doc_lib
            };
          } else if (typeArr[i] == "department_doc_lib") {
            typeArr[i] = {
              key: 1,
              title: "部门文档库",
              isLeaf: false,
              children: department_doc_lib
            };
          } else if (typeArr[i] == "custom_doc_lib") {
            typeArr[i] = {
              key: 2,
              title: "自定义文档库",
              isLeaf: false,
              children: custom_doc_lib
            };
          } else if (typeArr[i] == "shared_user_doc_lib") {
            typeArr[i] = {
              key: 3,
              title: "共享个人文档库",
              isLeaf: false,
              children: shared_user_doc_lib
            };
          } else if (typeArr[i] == "knowledge_doc_lib") {
            typeArr[i] = {
              key: 4,
              title: "知识库",
              isLeaf: false,
              children: knowledge_doc_lib
            };
          }
        }
  
        setTreeData(typeArr)
      }).catch(err => console.log('Request Failed', err));
    }, [])
  
    const onLoadData = ({
      key,
      children
    }) =>
      new Promise((resolve) => {
        if (children) {
          resolve();
          return;
        }
  
        fetch(`${props.baseApi}/api/efast/v1/dir/list`, {
          method: "POST",
          headers: {
            'authorization': "Bearer " + props.token
          },
          body: JSON.stringify({
            docid: key
          }),
        }).then((response) => response.json()).then(resJson => {
  
          const options = [];
  
          for (let i = 0; i < resJson.dirs.length; i++) {
            options.push({
              key: resJson.dirs[i]["docid"],
              title: resJson.dirs[i]["name"],
              isLeaf: false
            });
          }
  
          for (let i = 0; i < resJson.files.length; i++) {
            options.push({
              key: resJson.files[i]["docid"],
              title: resJson.files[i]["name"],
              isLeaf: true
            });
          }
  
          setTreeData((origin) =>
            updateTreeData(origin, key, options),
          );
          resolve();
  
        }).catch(err => console.log('Request Failed', err));
      });
  
    const onCheck = (checkedKeys, info) => {
      console.log('onCheck', checkedKeys, info);
      props.clickTree(info);
    };
  
    return <Tree switcherIcon={<DownOutlined />} loadData={
      onLoadData
    }
      treeData={
        treeData
      }
      checkable={
        true
      }
      blockNode selectable={
        false
      }
      onCheck={onCheck}
    />;
  };
  
  export default App;

异步加载TS版:

// App.tsx
import React from 'react';
import './App.css';
import AnyShareTree from "./AnyShareTree"

function App() {
  const onCheckTree = (value: any) => {
    console.log(value, "test")
  }

  return (
    <div className="App">
      <AnyShareTree clickTree={onCheckTree} baseApi={"https://anyshare.aishu.cn"} token={"kx7e88Kd-GtUgdc43V2gd-PfYufsgpbPWK0OP9ieGOs.uymaPkjLUnq3-Cxo8zZ2Fi3WhW_d5U3s1LsMtIs2jvE"} />
    </div>
  );
}


export default App;

// AsTree.tsx
import { DownOutlined } from '@ant-design/icons';
import {
    Tree, message
} from 'antd';
// import type { DataNode, TreeProps } from 'antd/es/tree';
import React, {
    useState,
    useEffect
} from 'react';
import './App.css';

const AS_DownOutlined: any = DownOutlined;

interface DataNode {
    title: string;
    key: string;
    isLeaf?: boolean;
    children?: DataNode[];
}

interface IProps {
    baseApi: string;
    token: string;
    clickTree: (value: any) => any;
}

const updateTreeData = (list: DataNode[], key: React.Key, children: DataNode[]): DataNode[] =>
    list.map((node) => {
        if (node.key === key) {
            return {
                ...node,
                children
            };
        }

        if (node.children) {
            return {
                ...node,
                children: updateTreeData(node.children, key, children)
            };
        }

        return node;
    });

const App: React.FC<IProps> = (props: IProps) => {
    const [treeData, setTreeData] = useState<DataNode[] | []>([]);

    useEffect(() => {
        fetch(`${props.baseApi}/api/efast/v1/entry-doc-lib`, {
            method: "GET",
            headers: {
                'authorization': "Bearer " + props.token
            }
        }).then((response) => {
            if (response.ok) {
                return response.json()
            } else {
                return Promise.reject({
                    status: response.status,
                    statusText: response.statusText,
                    url: response.url
                })
            }
        }).then(resJson => {
            const typeArr: any = [];
            const user_doc_lib = [];
            const department_doc_lib = [];
            const custom_doc_lib = [];
            const shared_user_doc_lib = [];
            const knowledge_doc_lib = [];

            for (let i = 0; i < resJson.length; i++) {
                if (typeArr.indexOf(resJson[i].type) < 0) {
                    typeArr.push(resJson[i].type);
                }

                if (resJson[i].type === "user_doc_lib") {
                    user_doc_lib.push({
                        key: resJson[i]["id"],
                        title: resJson[i]["name"],
                        isLeaf: false
                    });
                } else if (resJson[i].type === "department_doc_lib") {
                    department_doc_lib.push({
                        key: resJson[i]["id"],
                        title: resJson[i]["name"],
                        isLeaf: false
                    });
                } else if (resJson[i].type === "custom_doc_lib") {
                    custom_doc_lib.push({
                        key: resJson[i]["id"],
                        title: resJson[i]["name"],
                        isLeaf: false
                    });
                } else if (resJson[i].type === "shared_user_doc_lib") {
                    shared_user_doc_lib.push({
                        key: resJson[i]["id"],
                        title: resJson[i]["name"],
                        isLeaf: false
                    });
                } else if (resJson[i].type === "knowledge_doc_lib") {
                    knowledge_doc_lib.push({
                        key: resJson[i]["id"],
                        title: resJson[i]["name"],
                        isLeaf: false
                    });
                }
            }

            for (let i = 0; i < typeArr.length; i++) {
                if (typeArr[i] === "user_doc_lib") {
                    typeArr[i] = {
                        key: 0,
                        title: "个人文档库",
                        isLeaf: false,
                        children: user_doc_lib
                    };
                } else if (typeArr[i] === "department_doc_lib") {
                    typeArr[i] = {
                        key: 1,
                        title: "部门文档库",
                        isLeaf: false,
                        children: department_doc_lib
                    };
                } else if (typeArr[i] === "custom_doc_lib") {
                    typeArr[i] = {
                        key: 2,
                        title: "自定义文档库",
                        isLeaf: false,
                        children: custom_doc_lib
                    };
                } else if (typeArr[i] === "shared_user_doc_lib") {
                    typeArr[i] = {
                        key: 3,
                        title: "共享个人文档库",
                        isLeaf: false,
                        children: shared_user_doc_lib
                    };
                } else if (typeArr[i] === "knowledge_doc_lib") {
                    typeArr[i] = {
                        key: 4,
                        title: "知识库",
                        isLeaf: false,
                        children: knowledge_doc_lib
                    };
                }
            }

            setTreeData(typeArr)
        }).catch(err => message.error(JSON.stringify(err)));
    }, [])

    const onLoadData = ({
        key,
        children
    }: any) =>
        new Promise<void>((resolve) => {
            if (children) {
                resolve();
                return;
            }

            fetch(`${props.baseApi}/api/efast/v1/dir/list`, {
                method: "POST",
                headers: {
                    'authorization': "Bearer " + props.token
                },
                body: JSON.stringify({
                    docid: key
                }),
            }).then((response) => {
                if (response.ok) {
                    return response.json()
                } else {
                    return Promise.reject({
                        status: response.status,
                        statusText: response.statusText,
                        url: response.url
                    })
                }
            }).then(resJson => {

                const options: any[] = [];

                for (let i = 0; i < resJson.dirs.length; i++) {
                    options.push({
                        key: resJson.dirs[i]["docid"],
                        title: resJson.dirs[i]["name"],
                        isLeaf: false
                    });
                }

                for (let i = 0; i < resJson.files.length; i++) {
                    options.push({
                        key: resJson.files[i]["docid"],
                        title: resJson.files[i]["name"],
                        isLeaf: true
                    });
                }

                setTreeData((origin) =>
                    updateTreeData(origin, key, options),
                );
                resolve();

            }).catch(err => message.error(JSON.stringify(err)));
        });

    const onCheck: any = (checkedKeys: any, info: any) => {
        console.log('onCheck', checkedKeys, info);
        props.clickTree(info);
    };

    return <Tree switcherIcon={<AS_DownOutlined />} loadData={onLoadData} treeData={treeData} checkable={true} blockNode selectable={false} onCheck={onCheck} />;
};

export default App;

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Ant Design VueTree组件,您可以使用异步数据来实现选节点就展开节点的功能。以下是实现该功能的步骤: 1. 定义Tree节点的数据源,包括节点的id、名称、父节点id等属性。 2. 在Tree组件设置show-expand属性为true,这将显示展开和折叠图标。 3. 设置Tree组件的load-data属性,指定异步数据的方法,该方法将根据父节点id节点数据。 4. 在Tree组件节点模板使用 @click.native 事件监听节点的点击事件,并在事件处理程序判断当前节点是否有节点,如果有则展开,否则不展开。 下面是一个示例代码,用于实现选节点就展开节点的功能: ```html <template> <a-tree :show-expand="true" :load-data="loadData" :tree-data="treeData" > <template slot-scope="{ data }"> <span :class="{'tree-node-disabled': data.disabled}" @click.native="handleClick(data)" > {{ data.title }} </span> </template> </a-tree> </template> <script> export default { data() { return { treeData: [], }; }, mounted() { this.loadData(null, (data) => { this.treeData = data; }); }, methods: { loadData(parent, callback) { // 根据父节点id节点数据 // ... }, handleClick(node) { // 判断当前节点是否有节点 if (node.children && node.children.length > 0) { // 展开节点 node.expanded = !node.expanded; } }, }, }; </script> ``` 在上面的示例代码,loadData方法用于异步节点数据,handleClick方法用于处理节点的点击事件。当用户单击节点时,如果该节点节点,则会展开节点,否则不会展开。请按照您的实际需求进行修改。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值