我是靠谱客的博主 清爽西牛,这篇文章主要介绍关于antd tree和父子组件之间的传值问题(react 总结),现在分享给大家,希望可以做个参考。

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

写了三个组件:

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

现在可以分部解决问题:

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

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

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

4.form组件中的inquery方法:

现附上tree.js代码

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
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代码:

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
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 父子组件传值的资料请关注靠谱客其它相关文章!

最后

以上就是清爽西牛最近收集整理的关于关于antd tree和父子组件之间的传值问题(react 总结)的全部内容,更多相关关于antd内容请搜索靠谱客的其他文章。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(160)

评论列表共有 0 条评论

立即
投稿
返回
顶部