关于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 相关文章推荐
深入聊聊Array的sort方法的使用技巧.详细点评protype.js中的sortBy方法
Apr 12 Javascript
Firefox window.close()的使用注意事项
Apr 11 Javascript
js读取注册表的键值示例
Sep 25 Javascript
JavaScript中的console.assert()函数介绍
Dec 29 Javascript
angularJS提交表单(form)
Feb 09 Javascript
jQuery动画效果实现图片无缝连续滚动
Jan 12 Javascript
Linux下为Node.js程序配置MySQL或Oracle数据库的方法
Mar 19 Javascript
浅谈javascript:两种注释,声明变量,定义函数
Oct 05 Javascript
Vue表单类的父子组件数据传递示例
May 03 Javascript
详解基于vue的服务端渲染框架NUXT
Jun 20 Javascript
VUE安装使用教程详解
Jun 03 Javascript
基于JavaScript获取base64图片大小
Oct 18 Javascript
使用react+redux实现计数器功能及遇到问题
微信小程序基础教程之echart的使用
vue实现水波涟漪效果的点击反馈指令
vue 实现上传组件
May 31 #Vue.js
vue基于Teleport实现Modal组件
Vue+Element UI实现概要小弹窗的全过程
vue-cli4.5.x快速搭建项目
You might like
如何使用动态共享对象的模式来安装PHP
2006/10/09 PHP
Symfony2开发之控制器用法实例分析
2016/02/05 PHP
JavaScript 创建对象
2009/07/17 Javascript
javascript 动态table添加colspan\rowspan 参数的方法
2009/07/25 Javascript
读JavaScript DOM编程艺术笔记
2011/11/15 Javascript
JS图片预加载 JS实现图片预加载应用
2012/12/03 Javascript
jQuery左侧大图右侧小图焦点图幻灯切换代码分享
2015/08/19 Javascript
JavaScript统计网站访问次数的实现代码
2015/11/18 Javascript
理解javascript中DOM事件
2015/12/25 Javascript
基于jQuery Ajax实现上传文件
2016/03/24 Javascript
tab栏切换原理
2017/03/22 Javascript
深入浅析AngularJs模版与v-bind
2018/07/06 Javascript
tracking.js页面人脸识别插件使用方法
2020/04/16 Javascript
vue项目打包之后背景样式丢失的解决方案
2019/01/17 Javascript
jQuery 选择方法及$(this)用法实例分析
2020/05/19 jQuery
python用于url解码和中文解析的小脚本(python url decoder)
2013/08/11 Python
Django中使用group_by的方法
2015/05/26 Python
Python基于Tkinter的HelloWorld入门实例
2015/06/17 Python
python 实现求解字符串集的最长公共前缀方法
2018/07/20 Python
python实现整数的二进制循环移位
2019/03/08 Python
树莓派动作捕捉抓拍存储图像脚本
2019/06/22 Python
python安装requests库的实例代码
2019/06/25 Python
Numpy 中的矩阵求逆实例
2019/08/26 Python
使用python快速实现不同机器间文件夹共享方式
2019/12/22 Python
python实现猜数游戏(保存游戏记录)
2020/06/22 Python
keras自动编码器实现系列之卷积自动编码器操作
2020/07/03 Python
Giglio德国网上精品店:奢侈品服装和配件
2016/09/23 全球购物
anello泰国官方网站:日本流行包包品牌
2019/08/08 全球购物
大三毕业自我鉴定
2014/01/15 职场文书
竞选生活委员演讲稿
2014/04/28 职场文书
体操比赛口号
2014/06/10 职场文书
工作失误检讨书(经典集锦版)
2014/10/17 职场文书
医学专业大学生职业生涯规划书
2014/10/25 职场文书
2015年度公共机构节能工作总结
2015/05/26 职场文书
导游词之澳门妈祖庙
2019/12/19 职场文书
PyTorch中permute的使用方法
2022/04/26 Python