欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

关于antd tree 和父子组件之间的传值问题(react 总结)

程序员文章站 2022-07-03 17:36:42
项目需求:点击产品树节点时获取该节点的所有父节点,同时回填表格的搜索条件,完成搜索功能,搜索结果展示在下方的table中。写了三个组件:现在有个业务场景交互:在ordertree组件中点击树节点,获取...

项目需求:点击产品树节点时获取该节点的所有父节点,同时回填表格的搜索条件,完成搜索功能,搜索结果展示在下方的table中。

关于antd tree 和父子组件之间的传值问题(react 总结)

写了三个组件:

关于antd tree 和父子组件之间的传值问题(react 总结)

现在有个业务场景交互:在ordertree组件中点击树节点,获取当前节点以及所有的父节点的id 放入一个对象arrkeys中,并在orderform组件中使用(回填类型下拉选择框,objid对象作为查询接口的入参)

现在可以分部解决问题:

1.首先获取点击的树节点以及所有父节点的id ---arrkeys

关于antd tree 和父子组件之间的传值问题(react 总结)

关于antd tree 和父子组件之间的传值问题(react 总结)

关于antd tree 和父子组件之间的传值问题(react 总结)

2.在点击树节点获取当前节点以及所有父级节点之后,通过this.props.idobject(arrkeys)把 arrkeys传给父组件。

关于antd tree 和父子组件之间的传值问题(react 总结)

3.在tree组件和form组件中的componentdidmount生命周期中把整个组件传给父组件

关于antd tree 和父子组件之间的传值问题(react 总结)

4.form组件中的inquery方法:

关于antd tree 和父子组件之间的传值问题(react 总结)

现附上tree.js代码

import react, { component } from 'react';
import { connect } from 'dva';
import { divider, modal, table, message, tag, spin } from 'antd';
import router from 'umi/router';
import style from '../style.less';
import { tree, input } from 'antd';

const { confirm } = modal;
const { treenode } = tree;
const { search } = input;
let datalist = [];
let keysobj = {}; // 当前节点以及所有父节点的id
let firstparentkey = {}; // 一级根节点的id
const intetorfun = (data, key, string) => {
  if (string) {
    firstparentkey = {
      [data.param]: data.paramid,
    };
  }
  if (data.children && data.children.length !== 0) {
    data.children.foreach(item => {
      if (item.id === key[0]) {
        keysobj = {
          [data.param]: data.paramid,
          [item.param]: item.paramid,
          ...firstparentkey,
        };
      } else {
        intetorfun(item, key);
      }
    });
  }
  return keysobj;
};
const getparentkey = (key, tree) => {
  let parentkey = [];
  for (let i = 0; i < tree.length; i++) {
    const node = tree[i];
    parentkey = intetorfun(node, key, 'firsttime');
  }
  return parentkey;
};
//搜索用的
const getsearchkey = (key, tree) => {
  let parentkey;
  for (let i = 0; i < tree.length; i++) {
    const node = tree[i];
    if (node.children) {
      if (node.children.some(item => item.id === key)) {
        parentkey = node.id;
      } else if (getsearchkey(key, node.children)) {
        parentkey = getsearchkey(key, node.children);
      }
    } else {
      if (node.id === key) {
        parentkey = node.id;
      }
    }
  }
  return parentkey;
};

@connect(({ commodity, loading, menu }) => ({
  commodity,
  loading: loading.effects['commodity/gettree'],
  menu,
}))
class ordertree extends component {
  constructor(props) {
    super(props);
    this.state = {
      expandedkeys: [], //默认展开一级根节点 props.commodity.defaultparentidlist
      searchvalue: '',
      autoexpandparent: true,
    };
  }
  componentdidmount() {
    const { dispatch } = this.props;
    this.props.treeref && this.props.treeref(this); //挂载时把整个tree组件传给父组件
    dispatch({
      type: 'commodity/gettree',
      callback: res => {
        this.generatelist(res.data);
        const defaultparentidlist = res.data.map(item => item.id);
        this.setstate({
          expandedkeys: defaultparentidlist,
        });
      },
    });
  }
  generatelist = data => {
    const { dispatch } = this.props;
    for (let i = 0; i < data.length; i++) {
      const node = data[i];
      const { id, name } = node;
      datalist.push({ id, name });
      dispatch({
        type: 'commodity/save',
        payload: {
          datalist,
        },
      });
      if (node.children) {
        this.generatelist(node.children);
      }
    }
  };

  //展开/收起节点时触发
  onexpand = expandedkeys => {
    this.setstate({
      expandedkeys,
      autoexpandparent: true,
    });
  };
  //点击树节点时触发
  onselect = (selectkeys, e) => {
    const { dispatch } = this.props;
    const {
      commodity: { treedata },
    } = this.props;
    let arrkeys = {};
    //只有节点选中了才执行代码 dataref是自定义在treenode上添加的属性,可以获取当前节点的所有信息
    if (e.selected && e.node.props.dataref.param !== 'categoryid') {
      keysobj = {};
      firstparentkey = {};
      arrkeys = getparentkey(selectkeys, treedata);
    } else if (e.selected && e.node.props.dataref.param === 'categoryid') {
      keysobj = {};
      firstparentkey = {};
      arrkeys = {
        categoryid: e.node.props.dataref.paramid,
      };
    } else if (!e.selected) {
      return false;
    }
    this.props.idobject(arrkeys);
  };
  // 搜索功能
  onchange = e => {
    const { value } = e.target;
    const {
      commodity: { treedata, datalist, defaultparentidlist },
    } = this.props;
    let expandedkeys = [];
    if (value) {
      expandedkeys = datalist
        .map(item => {
          if (item.name.tolowercase().indexof(value.tolowercase()) > -1) {
            //不区分大小写
            return getsearchkey(item.id, treedata);
          }
          return null;
        })
        .filter((item, i, self) => item && self.indexof(item) === i);
      this.setstate({
        expandedkeys,
        searchvalue: value,
        autoexpandparent: true,
      });
    } else {
      this.setstate({
        expandedkeys: defaultparentidlist,
        searchvalue: '',
        autoexpandparent: true,
      });
    }
  };

  render() {
    const { searchvalue, expandedkeys, autoexpandparent } = this.state;
    const {
      commodity: { treedata },
      loading,
    } = this.props;
    const loop = data =>
      data.map(item => {
        const index = item.name.tolowercase().indexof(searchvalue.tolowercase()); //忽略大小写
        const beforestr = item.name.substr(0, index);
        const afterstr = item.name.substr(index + searchvalue.length);
        const centerstr = item.name.substr(index, searchvalue.length);
        const title =
          index > -1 ? (
            <span title={item.name}>
              {beforestr}
              <span style={{ color: '#f50' }}>{centerstr}</span>
              {afterstr}
            </span>
          ) : (
            <span title={item.name}>{item.name}</span>
          );
        if (item.children) {
          return (
            <treenode key={item.id} title={title} dataref={item}>
              {loop(item.children)}
            </treenode>
          );
        }
        return <treenode key={item.id} title={title} dataref={item} />;
      });
    return (
      <spin spinning={loading}>
        <div>
          <search style={{ marginbottom: 8 }} placeholder="search" onchange={this.onchange} />
          <tree
            onexpand={this.onexpand}
            onselect={this.onselect}
            expandedkeys={expandedkeys}
            autoexpandparent={autoexpandparent}
          >
            {loop(treedata)}
          </tree>
        </div>
      </spin>
    );
  }
}

export default ordertree;

父组件index.js代码:

import react, { component } from 'react';
import { connect } from 'dva';
import { formatmessage, formattedmessage } from 'umi/locale';
import { card, spin } from 'antd';
import pageheaderwrapper from '@/components/pageheaderwrapper';
import orderform from './components/form';
import ordertable from './components/table';
import ordertree from './components/tree';
import style from './style.less';
import { consoletestresulthandler } from 'tslint/lib/test';

// let datalist = [];

@connect(({ commodity, loading, menu }) => ({
  commodity,
  loading: loading.effects['commodity/gettree'],
  menu,
}))
class orderpage extends component {
  constructor() {
    super();
    this.state = {
      idobject: {},
      reactflag: false,
    };
  }
  componentdidmount() {
    const { dispatch } = this.props;
    dispatch({
      type: 'commodity/getgoodscategory',
    });
  }
  onref = ref => {
    this.orderform = ref;
  };
  treeref = ref => {
    this.ordertree = ref;
  };
  getidobject = data => {
    this.setstate(
      {
        idobject: data,
      },
      () => {
        this.orderform.props.form.setfieldsvalue({
          categoryids: [string(data.categoryid)],
        });
        this.orderform.inquery(data);
      }
    );
  };
  //判断是否点击重置按钮
  isreact = ref => {
    const {
      commodity: { defaultparentidlist },
    } = this.props;
    if (ref) {
      this.ordertree.setstate({
        expandedkeys: defaultparentidlist,
      });
    }
  };

  render() {
    return (
      <pageheaderwrapper logo>
        <card bordered={false} title="商品spu列表" classname={style.antcardbox}>
          <div
            style={{ width: '350px', marginright: '30px', boxshadow: '3px -3px 6px 0px #ccc6' }}
            classname={style.anttreebox}
          >
            <ordertree idobject={this.getidobject} treeref={this.treeref} />
          </div>
          <div style={{ flex: '1' }}>
            <orderform onref={this.onref} isreact={this.isreact} />
            <ordertable />
          </div>
        </card>
      </pageheaderwrapper>
    );
  }
}

export default orderpage;

以上就是关于antd tree 和父子组件之间的传值问题(react 总结)的详细内容,更多关于antd tree 父子组件传值的资料请关注其它相关文章!