Antd Tree简单使用

最近在做新项目,用的umi框架,使用的Antd的UI组件,之前也了解过Antd的使用,但是实际自己写起来才发现有好多问题

  1. 从新项目开始到现在,查antd文档最多的就是树形控件Tree,可能是比较复杂吧,并且项目中的需求和之前的不一样,好多地方都需要重新看文档实现。
  2. 异步加载树节点数据,需要实现tree的loadData方法
  • 官方实例中的渲染树节点方法
    renderTreeNodes = data =>
      data.map(item => {
        if (item.children) {
          return (
            <TreeNode title={item.title} key={item.key} dataRef={item}>
              {this.renderTreeNodes(item.children)}
            </TreeNode>
          );
        }
        return <TreeNode key={item.key} {...item} dataRef={item} />;
      });
    
  • 官方实例中的加载方法
    onLoadData = treeNode =>
      new Promise(resolve => {
        if (treeNode.props.children) {//如果树节点已经有子节点时,返回
          resolve();
          return;
        }
        setTimeout(() => {//模拟请求,结束后设置数据源的children属性
          treeNode.props.dataRef.children = [
            { title: 'Child Node', key: `${treeNode.props.eventKey}-0` },
            { title: 'Child Node', key: `${treeNode.props.eventKey}-1` },
          ];
          this.setState({
            treeData: [...this.state.treeData],
          });
          resolve();
        }, 1000);
      });
    
  • 使用umi框架,加载方法
    onLoadData = (treeNode) => {
      return this.props.dispatch({
        type: 'catalogue/getCatalogueChildList',
        payload: {
          type: this.props.type,
          id: treeNode.props.dataRef.id,
        },
      });
    };
    //model中的网络请求,获取子节点方法
    *getCatalogueChildList({ payload }, { select, call, put }) {
      const res = yield call(getCatalogueChildList, payload);
      if (res && res.success) {
        const catalogue = yield select((_) => _.catalogue);
        let catalogues = catalogue.catalogues;
        const parentCatalogue = catalogues.filter(
          (catalogue) => catalogue.id == payload.id,
        )[0];
        if (parentCatalogue) {
          parentCatalogue.children = res.data.data;//设置子节点为父节点的children属性
          yield put({
            type: 'updateState',
            payload: {
              catalogues: catalogues,
            },
          });
        }
      } else {
        console.log(res);
      }
    },
    
  1. 树节点上添加自定义按钮
  • 想直接复制之前项目中的代码,但是看了发现写的有点复杂,通过自定义树节点和监听鼠标事件,来控制按钮显示和隐藏,所以就想有没有简单点的方法
  • 在网上查了查,发现可以直接通过css中的hover状态来控制
    .ant-tree-node-content-wrapper {
      width: calc(100% - 32px);
      .ant-tree-title > span span {
        width: calc(100% - 16px);
        display: inline-block;
      }
      .ant-tree-title > span .anticon {
        display: none;
      }
    }
    .ant-tree-node-content-wrapper:hover {
      background-color: rgba(24, 144, 255, 0.1);
      .ant-tree-title > span .anticon {
        display: inline-block;
      }
    }
    
  • 渲染树节点的方法
    renderTreeNodes = (data) => {
      return (
        data &&
        data.map((item) => {
          if (item.children) {
            return (
              <Tree.TreeNode
                title={
                  <span>
                    <span>{item.title}</span>
                    <Icon
                      type='copy'
                      style={{float: 'right', marginTop: 5}}
                      onClick={(e)=>this.copyCatalogueId(e, item)}
                    />
                  </span>
                }
                key={item.id}
                dataRef={item}
                isLeaf={item.contentType != 1}
              >
                {this.renderTreeNodes(item.children)}
              </Tree.TreeNode>
            );
          }
          return (
            <Tree.TreeNode
              key={item.id}
              title={
                <span>
                  <span>{item.title}</span>
                  <Icon
                    type='copy'
                    style={{float: 'right', marginTop: 5}}
                    onClick={(e)=>this.copyCatalogueId(e, item)}
                  />
                </span>}
              dataRef={item}
              isLeaf={item.contentType != 1}
            />
          );
        })
      );
    };
    
  1. 复制文本方法
    //创建input元素,把文字设置到input里面,执行execCommand的copy方法复制
    copyCatalogueId = (e, item) => {
      const input = document.createElement('input');
      document.body.appendChild(input);
      input.setAttribute('value', item.contentCode);
      input.select();
      document.execCommand('copy');
      message.success('目录编码复制成功!');
      document.body.removeChild(input);
    
      e.stopPropagation();//阻止冒泡
    };
    
上一篇:antd-vue表格二次封装定制化


下一篇:antd Form失去焦点时校验、确认密码特殊校验