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


Posted in Javascript onJune 02, 2021

项目需求:点击产品树节点时获取该节点的所有父节点,同时回填表格的搜索条件,完成搜索功能,搜索结果展示在下方的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 父子组件传值的资料请关注三水点靠木其它相关文章!

Javascript 相关文章推荐
你所要知道JS(DHTML)中的一些技巧
Jan 09 Javascript
用javascript动态调整iframe高度的方法
Mar 06 Javascript
神奇的7个jQuery 3D插件整理
Jan 06 Javascript
一些老手都不一定知道的JavaScript技巧
May 06 Javascript
node.js+Ajax实现获取HTTP服务器返回数据
Nov 26 Javascript
AngularJS基础学习笔记之控制器
May 10 Javascript
Jquery修改image的src属性,图片不加载问题的解决方法
May 17 Javascript
input框中的name和id的区别
Nov 16 Javascript
详解Angualr 组件间通信
Jan 21 Javascript
详解RequireJs官方使用教程
Oct 31 Javascript
angularjs 缓存的使用详解
Mar 19 Javascript
vue与django集成打包的实现方法
Nov 11 Javascript
使用react+redux实现计数器功能及遇到问题
微信小程序基础教程之echart的使用
vue实现水波涟漪效果的点击反馈指令
vue 实现上传组件
May 31 #Vue.js
vue基于Teleport实现Modal组件
Vue+Element UI实现概要小弹窗的全过程
vue-cli4.5.x快速搭建项目
You might like
各种快递查询--Api接口
2016/04/26 PHP
php版微信公众平台之微信网页登陆授权示例
2016/09/23 PHP
PHP标准类(stdclass)用法示例
2016/09/28 PHP
php解决crontab定时任务不能写入文件问题的方法分析
2019/09/16 PHP
Javascript实例教程(19) 使用HoTMetal(3)
2006/12/23 Javascript
JS 控件事件小结
2012/10/31 Javascript
jQuery中(function(){})()执行顺序的理解
2013/03/05 Javascript
JS随机漂浮广告代码具体实例
2013/11/19 Javascript
浅谈jQuery异步对象(XMLHttpRequest)
2014/11/17 Javascript
node.js中的console.dir方法使用说明
2014/12/10 Javascript
HTML5 Shiv完美解决IE(IE6/IE7/IE8)不兼容HTML5标签的方法
2015/11/25 Javascript
JS实现本地存储信息的方法(基于localStorage与userData)
2017/02/18 Javascript
JSON创建键值对(key是中文或者数字)方式详解
2017/08/24 Javascript
Vue 兄弟组件通信的方法(不使用Vuex)
2017/10/26 Javascript
vue实现树形菜单效果
2018/03/19 Javascript
原生js实现拖拽功能基本思路详解
2018/04/18 Javascript
JavaScript布尔运算符原理使用解析
2020/05/06 Javascript
python模拟enum枚举类型的方法小结
2015/04/30 Python
Django中传递参数到URLconf的视图函数中的方法
2015/07/18 Python
Python set常用操作函数集锦
2017/11/15 Python
python pytest进阶之fixture详解
2019/06/27 Python
利用Python进行图像的加法,图像混合(附代码)
2019/07/14 Python
python django model联合主键的例子
2019/08/06 Python
Python Subprocess模块原理及实例
2019/08/26 Python
numpy ndarray 按条件筛选数组,关联筛选的例子
2019/11/26 Python
windows上彻底删除jupyter notebook的实现
2020/04/13 Python
全网首秀之Pycharm十大实用技巧(推荐)
2020/04/27 Python
html5 worker 实例(一) 为什么测试不到效果
2013/06/24 HTML / CSS
意大利会呼吸的鞋:Geox健乐士
2017/02/12 全球购物
个人贷款担保书
2014/04/01 职场文书
年会邀请函范文
2015/01/30 职场文书
中班下学期个人工作总结
2015/02/12 职场文书
Python基础之元编程知识总结
2021/05/23 Python
Redis性能监控的实现
2021/07/09 Redis
threejs太阳光与阴影效果实例代码
2022/04/05 Javascript
SpringCloud超详细讲解Feign声明式服务调用
2022/06/21 Java/Android