详情请点阅读全文
一、静态页面
目录结构
F:\Test\react-demo\admin-client\src\pages\admin\category
1 | add-cate-form.jsx |
1. pages/category/index.jsx
1 | import React,{Component} from 'react' |
二、动态:产品分类数据请求
1.编写产品分类相关接口src/api/index.js
【1】获取产品一级/二级分类列表接口
【2】添加产品分类接口
【3】修改产品分类接口
1 | import ajax from './ajax' |
2. 获取数据category/index.jsx
1 | import React,{Component} from 'react' |
效果同一.1
3. 优化:加载数据动画、分页显示
【1】控制是否显示加载动画
【2】设置加载中动画状态显示
【3】数据加载完成,取消loading动画显示
【4】对state里数据解构
【5】分页配置:每页显示数量,显示快速跳转
【6】加载动画、
1 | import React,{Component} from 'react' |
效果:加载时显示加载中动画、每页显示5条数据(默认十条)
三、二级产品分类及面包屑
3.1 点一级分类进入对应子分类列表,
3.2 头部加面包屑,在子页面显示对应首页分类名
【1】初始为0即请求一级产品分类列表
【2】当前子分类的对应父分类名
【3】子分类列表数据
【4】parentId等于传进来的参数或state里的值
【5】把0改为从state内动态获取,请求分类数据并赋值给result
【6】如果parentId=0则是一级列表,执行:
【7】否则是二级列表,执行:
【8】数据源、如果parentId为0设置一级分类列表为数据源、否则二级分类为列表源
【9.0】参数:当前条目的数据对象,返回需要显示的界面标签
【9.1】添加事件监听点击时调用显示函数
因为如果加括号及参数就会自动执行函数,而不是点击后才执行,所以用一个匿名函数把它包起来
如果parentId=0即是父级列表则显示查看子分类按钮,否则什么也不显示
【10】显示一级分类对应二级产品分类函数
【11】先更新状state的parentId为对应新分类的id
【12】setState是异步执行,并不会马上更新完状态,
因此需在其内部写(在状态更新且重新render()后执行)
【20】卡片标题,如果是一及分类显示 一级分类列表,否则显示一级分类+链接+对应的一级分类名
【21】显示一级分类函数,设置id状态即可
1 | import React,{Component} from 'react' |
效果:http://localhost:3000/category
四、添加分类、更新分类基础布局
4.1引进对话框、添加函数框架
【1】引入对话框
【2】添加分类、更新分类显示状态,0:都不显示,1:显示添加,2:显示更新
【3】对state里数据解构:
【4】添加对话框:0:都不显示,1:显示添加分类,2:显示更新分类
【5】添加监听函数:addCate,updateCate,handleCancel
【6】添加分类函数
【7】更新分类函数updateCate
【8】取消对话框函数handleCancel
【9】添加监听updateCate
【10】卡片右侧添加按键:添加监听
1 | import React,{Component} from 'react' |
4.2编写添加分类界面pages/category/add-cate-form
1 | import React,{Component} from 'react' |
pages/category/index.jsx引入刚写的组件
【20】添加分类表单
【21】使用<AddCateForm组件
1 | import AddCateForm from './add-cate-form';//【20】添加分类表单 |
4.4 表单返回数值获取知识点
官网文档:https://ant.design/components/form-cn/#Form.create(options)
1 | improt {Form} from 'antd' |
完整代码add-cate-form.jsx
1 | import React,{Component} from 'react' |
4.5编写修改分类界面pages/category/update-cate-form.jsx
到此和4.4代码相同,换个类名即可
1 | import React,{Component} from 'react' |
4.6效果:http://localhost:3000/category
五、修改产品分类功能实现
1.点击修改分类时自动显示对应的分类名pages/category/index.jsx
【1】在updateCateForm组件加一个参数categoryName用于传给子组件, 实现更新时显示当前条目的产品分类名称
【2】把当前条目的数据对象传递给updateCate函数
【3】接收[2]传来的对应条目数据对象
【4】接收参数赋值到当前函数
【5】把4步收到的参数赋值给categoryObj
【6】转到update-cate-form.jsx内接收传过来的参数categoryName
1 | import React,{Component} from 'react' |
2.接收父组件传过来的属性值,实现显示对应条目的类名update-cate-from.jsx
【1】接收父组件传值组件
【2】把从父组件接收过来的属性参数接收过来
【3】把categoryName解构出来
【4】文本框默认值为父组件传过来的对应条目数据的名字
1 | import React,{Component} from 'react' |
效果:
3.执行修改产品分类
- 知识点,子向父组件传值
- form.resetFields()清除缓存
3.1 pages/category/index.jsx
【0】onOk点执行updateCate函数执行分类名修改
【1】执行修改分类(点对话框的ok按钮执行此函数)
【2】从子组件update-cate-form.jsx组件获取要修改的分类名
【3】接收子组件传来的form对象(向子组件传递带参数的函数,子组件调用它,再把from对象通过参数传回来)子组件把form对象传来之前,将其赋值到this.from里
【4】下接update-cate-form.jsx
【5】更新函数:重置所有表单数据,防止使用缓存,造成点其它条目时展示上一条修改的数据
【5】取消修改函数:重置所有表单数据,防止使用缓存,造成点其它条目时展示上一条修改的数据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
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259import React,{Component} from 'react'
import './index.less'
import {
Button,
Card,
Table,
Icon,
Modal, //引入对话框
message,} from 'antd';
import LinkButton from '../../../components/link-button'
import {reqCategorys,reqAddCategory,reqUpdateCategory} from '../../../api/' //获取api接口请求函数
import AddCateForm from './add-cate-form'; //添加分类表单
import UpdateCateForm from './update-cate-form'; //导入更新分类的表单
export default class Category extends Component{
state={
loading:false, //控制是否显示加载动画
parentId:'0', //初始为0即请求一级产品分类列表
categorys:[], //存放api接口获取的分类列表
parentName:'', //当前子分类的对应父分类名
subCategorys:[], //子分类列表数据
showStatus:0, //添加分类、更新分类显示状态,0:都不显示,1:显示添加,2:显示更新
}
//异步请求一级分类列表
getCategorys = async (parentId)=>{
this.setState({loading:true}) //设置加载中动画状态显示
parentId=parentId || this.state.parentId //parentId等于传进来的参数或state里的值
const result=await reqCategorys(parentId) //把0改为从state内动态获取,请求分类数据并赋值给result
if(result.status===0){ //如果返回的status=0,说明返回成功,执行:
console.log(result.data) //测试输出返回的数据
const categorys=result.data //把返回数据赋值给categorys
//如果parentId=0则是一级列表,执行:
if(parentId==='0'){
this.setState({
categorys, //(因为名称和state标签名相同,所以用简写)把返回的一级产品分类数据,赋值给state里
loading:false, //数据加载完成,取消loading动画显示
})
}else{//否则是二级列表,执行:
this.setState({
subCategorys:categorys, //把返回的二级产品分类数据,赋值给state里
loading:false, //数据加载完成,取消loading动画显示
})
}
}else{
message.error('获取分类列表失败')
}
}
//显示一级分类对应二级产品分类函数
showSubCategory=(category)=>{
//先更新状state的parentId为对应新分类的id
this.setState({
parentId:category._id,
parentName:category.name
},()=>{/*setState是异步执行,并不会马上更新完状态,
因此需在其内部写(在状态更新且重新render()后执行)*/
console.log('parentId',this.state.parentId)
this.getCategorys()//获取二级分类列表
})
}
//显示一级分类函数,设置id状态即可
showCategorys=()=>{
this.setState({
parentId:'0',
parentName:'',
subCategorys:[],
})
}
//初始化表格column列名函数
initColumn=()=>{
//表格列名
this.columns = [
{
title: '分类名',
key: 'name',
dataIndex: 'name',
},
{
title: '操作',
width:'29%',
render: (categoryObj) => (//category代表当前条目对象(名字随意),用于返回需要显示的界面标签
<span>
{/*把当前条目的数据对象传递给updateCate函数 */}
<LinkButton onClick={()=>this.showUpdateCate(categoryObj)}>修改分类</LinkButton>
{/*
添加事件监听点击时调用显示函数
因为如果加括号及参数就会自动执行函数,而不是点击后才执行,所以用一个匿名函数把它包起来
如果parentId=0即是父级列表则显示查看子分类按钮,否则什么也不显示
*/}
{this.state.parentId==='0'?<LinkButton onClick={()=>{this.showSubCategory(categoryObj)}}>查看子分类</LinkButton>:null}
</span>
),
},
];
}
//显示添加分类函数
showAddCate= async (parentId,categoryName)=>{
this.setState({
showStatus:1
})
}
//更新分类函数updateCate,接收[2]传来的对应条目数据对象
showUpdateCate=(categoryObj)=>{
//接收参数赋值到当前函数
this.categoryObj=categoryObj
this.setState({
showStatus:2
})
}
//取消对话框函数handleCancel
handleCancel=()=>{
//【6】重置所有表单数据,防止上一条数据修改后点取消,下一条使用缓存,点其它条目时展示上一条修改的数据
this.form.resetFields()
this.setState({
showStatus:0
})
}
//执行添加分类
AddCate= async (parentId,categoryName)=>{
const result = await reqAddCategory(parentId,categoryName)
if(result.status===0){
message.success('产品分类添加成功')
}else{
message.error('产品分类添加失败')
}
}
//【1】执行修改分类(点对话框的ok按钮执行此函数)
updateCate= async ()=>{
//1.点ok后隐藏对话框
this.setState({showStatus:0})
//2.准备数据
const categoryId=this.categoryObj._id
//【2】从子组件update-cate-form.jsx组件获取要修改的分类名
const categoryName=this.form.getFieldValue('categoryName') //取this的form对象
// console.log('categoryId:',categoryId)
// console.log('categoryName:',categoryName)
//【5】重置所有表单数据,防止使用缓存,造成点其它条目时展示上一条修改的数据
this.form.resetFields()
//3.发送请求更新分类
const result = await reqUpdateCategory({categoryId,categoryName})
if(result.status===0){
message.success('产品分类修改名称成功')
//4.重新显示修改名称后的分类列表
this.getCategorys()
}else{
message.error('产品分类修改名称失败')
}
}
// 页面完成加载后运行,用于异步加载等函数存放
componentDidMount(){
this.getCategorys() //获取表格数据源
}
// 页面将要加载运行:用于页面渲染前的数据准备
componentWillMount(){
this.initColumn() //准备表格列名相关数据
//this.addCate('5e41578325a557082c18f43b','洗衣机')
}
render(){
// 对state里数据解构:
const {categorys,subCategorys, parentId,parentName,loading,showStatus}=this.state
//把4步收到的参数赋值给categoryObj
const categoryOjb = this.categoryObj || {} // 如果还没有,则指定一个空对象
//卡片标题,如果是一及分类显示 一级分类列表,否则显示一级分类+链接+对应的一级分类名
const title= parentId==='0'?'一级分类列表':(
<span>
<LinkButton onClick={this.showCategorys}>一级分类列表</LinkButton> >>
<span>{parentName}</span>
</span>
)
//卡片右侧添加按键:添加监听
const extra=(
<Button type='primary' onClick={this.showAddCate}>
<Icon type='plus'/>
添加
</Button>
)
return(
<div className='category'>
{/*卡片样式组件*/}
<Card title={title} extra={extra} >
{/*
表格组件、边框、key为数据源的_id、
数据源、如果parentId为0设置一级分类列表为数据源、否则二级分类为列表源
列名定义、
一页显示数据条数,显示快速跳转
*/}
<Table
bordered
rowKey='_id'
dataSource={parentId==='0'? categorys:subCategorys}
columns={this.columns}
loading={loading}
pagination={{defaultPageSize: 5, showQuickJumper: true}}
/>
{/*添加对话框:0:都不显示,1:显示添加分类,2:显示更新分类
添加监听函数:addCate,updateCate,handleCancel
使用<AddCateForm组件
*/}
<Modal
title="添加分类"
visible={showStatus===1}
onOk={this.addCate}
onCancel={this.handleCancel}
>
<AddCateForm />
</Modal>
{/*
在updateCateForm组件加一个参数categoryName用于传给子组件,
实现更新时显示当前条目的产品分类名称
转到update-cate-form.jsx内接收传过来的参数categoryName
【0】onOk点执行updateCate函数执行分类名修改
*/}
<Modal
title="修改分类"
visible={showStatus===2}
onOk={this.updateCate}
onCancel={this.handleCancel}
>
{/*【3】接收子组件传来的form对象(向子组件传递带参数的函数,子组件调用它,再把from对象通过参数传回来)
子组件把form对象传来之前,将其赋值到this.from里
【4】下接update-cate-form.jsx*/}
<UpdateCateForm
categoryName={categoryOjb.name}
setForm={(form)=>{this.form=form}}
/>
</Modal>
</Card>
</div>
)
}
}3.2 update-cate-form.jsx
【1】设置setForm类型为函数且必须
【2】在此组件渲染之前调用一次setForm函数,把form传到父组件去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
68import React,{Component} from 'react'
import {
Form,
Select,
Input
} from 'antd'
import PropTypes from 'prop-types' //接收父组件传值组件
const Item=Form.Item
const Option=Select.Option
class UpdateCateForm extends Component{
//把从父组件接收过来的属性参数接收过来
static propTypes={
categoryName:PropTypes.string.isRequired,
//【1】设置setForm类型为函数且必须
setForm:PropTypes.func.isRequired,
}
//【2】在此组件渲染之前调用一次setForm函数,把form传到父组件去
componentWillMount(){
//将form对象通过setForm函数传给父组件
this.props.setForm(this.props.form)
}
render(){
//把categoryName解构出来
const {categoryName} = this.props
const { getFieldDecorator } = this.props.form
return(
<Form>
{/*<Item>
<span>所属分类:</span>
{
getFieldDecorator('parentId',{
initialValue:parentId
})(
<Select>
<Option value='1'>一级分类</Option>
</Select>
)
}
</Item>*/}
<Item>
{/**因为getFiledDecorator接收的标签必须为Form标签,因此span必须拿出来 */}
<span>修改分类名:</span>
{
getFieldDecorator('categoryName',{
//文本框默认值为父组件传过来的对应条目数据的名字
initialValue:categoryName,
rules:[
{required:true,message:'分类名称必须输入'}
]
})(
<Input type='text' placeholder='请输入子分类名称' />
)
}
</Item>
</Form>
)
}
}
export default Form.create()(UpdateCateForm);效果:同上,但修改一个条目后,再点下g 个条目不会显示之前修改的那个数据
六、添加产品分类功能实现
6.1添加分类组件完善add-cate-form.jsx
【1】引入父子传值模块
【2】引入父组件的传过来的相关属性
【3】到父组件category/index.jsx下把categorys[],parentId,from对象传过来
【4】取出父组件传过来的categorys,parentId
【5】令inintalValue=parentId(实现在子分类点添加分类时一级分类自动显示对应分类)、把一级分类动态写入(实现自动调取所有一级分类)、
【6】把当前组件的form作为参数运行一下父组件传过来的[接收子组件form对象函数],从而实现父组件也有form对象
【7】回到父组件实现功能
1 | import React,{Component} from 'react' |
6.2 添加分类功能实现:category/index.jsx
【1】把categorys,和parentId、接收子组件from对象的函数、传到子组件add-cate-form.jsx里面
【2】执行添加分类:
1.获取表单数据
2.清除表单数据
3.如果添加成功:
4.隐藏对话框,提示添加成功
5.重新加载产品分类
6.添加失败
1 | import React,{Component} from 'react' |
效果:http://localhost:3000/category
点【添加分类】成功添加分类,关闭对话框、显示添加成功、重新加载显示分类
6.3功能完善
问题:
在2级分类添加其它一级分类、一级分类对应子分类时,点过去看不到其对应分类(原因是添加后没请求2级分类)
解决,加个判断,在二级分类下添加一级分类/其它子分类,只请求分类列表,但不改变state.parentId即可。
【1】如果新添加的分类就是当前分类下的子分类(当前表单显示的parentId=状态中的parentId):
【2】如果添加的是一级分类(parentId===0),则需获取一级分类,但无需显示
【3】正常要重新设置state里的parentId=0然后再请求一次,但这样会造成跳转到一级分类
因此把parentId直接做为参数传到getCategorys()里,这样就不会跳转显示一级分类,还是在二级分类里了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
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284import React,{Component} from 'react'
import './index.less'
import {
Button,
Card,
Table,
Icon,
Modal, //引入对话框
message,} from 'antd';
import LinkButton from '../../../components/link-button'
import {reqCategorys,reqAddCategory,reqUpdateCategory} from '../../../api/' //获取api接口请求函数
import AddCateForm from './add-cate-form'; //添加分类表单
import UpdateCateForm from './update-cate-form'; //导入更新分类的表单
export default class Category extends Component{
state={
loading:false, //控制是否显示加载动画
parentId:'0', //初始为0即请求一级产品分类列表
categorys:[], //存放api接口获取的分类列表
parentName:'', //当前子分类的对应父分类名
subCategorys:[], //子分类列表数据
showStatus:0, //添加分类、更新分类显示状态,0:都不显示,1:显示添加,2:显示更新
}
//异步请求一级分类列表
getCategorys = async (parentId)=>{
this.setState({loading:true}) //设置加载中动画状态显示
parentId=parentId || this.state.parentId //parentId等于传进来的参数或state里的值
const result=await reqCategorys(parentId) //把0改为从state内动态获取,请求分类数据并赋值给result
if(result.status===0){ //如果返回的status=0,说明返回成功,执行:
console.log(result.data) //测试输出返回的数据
const categorys=result.data //把返回数据赋值给categorys
//如果parentId=0则是一级列表,执行:
if(parentId==='0'){
this.setState({
categorys, //(因为名称和state标签名相同,所以用简写)把返回的一级产品分类数据,赋值给state里
loading:false, //数据加载完成,取消loading动画显示
})
}else{//否则是二级列表,执行:
this.setState({
subCategorys:categorys, //把返回的二级产品分类数据,赋值给state里
loading:false, //数据加载完成,取消loading动画显示
})
}
}else{
message.error('获取分类列表失败')
}
}
//显示一级分类对应二级产品分类函数
showSubCategory=(category)=>{
//先更新状state的parentId为对应新分类的id
this.setState({
parentId:category._id,
parentName:category.name
},()=>{/*setState是异步执行,并不会马上更新完状态,
因此需在其内部写(在状态更新且重新render()后执行)*/
console.log('parentId',this.state.parentId)
this.getCategorys()//获取二级分类列表
})
}
//显示一级分类函数,设置id状态即可
showCategorys=()=>{
this.setState({
parentId:'0',
parentName:'',
subCategorys:[],
})
}
//初始化表格column列名函数
initColumn=()=>{
//表格列名
this.columns = [
{
title: '分类名',
key: 'name',
dataIndex: 'name',
},
{
title: '操作',
width:'29%',
render: (categoryObj) => (//category代表当前条目对象(名字随意),用于返回需要显示的界面标签
<span>
{/*把当前条目的数据对象传递给updateCate函数 */}
<LinkButton onClick={()=>this.showUpdateCate(categoryObj)}>修改分类</LinkButton>
{/*
添加事件监听点击时调用显示函数
因为如果加括号及参数就会自动执行函数,而不是点击后才执行,所以用一个匿名函数把它包起来
如果parentId=0即是父级列表则显示查看子分类按钮,否则什么也不显示
*/}
{this.state.parentId==='0'?<LinkButton onClick={()=>{this.showSubCategory(categoryObj)}}>查看子分类</LinkButton>:null}
</span>
),
},
];
}
//显示添加分类函数
showAddCate= async (parentId,categoryName)=>{
this.setState({
showStatus:1
})
}
//更新分类函数updateCate,接收[2]传来的对应条目数据对象
showUpdateCate=(categoryObj)=>{
//接收参数赋值到当前函数
this.categoryObj=categoryObj
this.setState({
showStatus:2
})
}
//取消对话框函数handleCancel
handleCancel=()=>{
//重置所有表单数据,防止上一条数据修改后点取消,下一条使用缓存,点其它条目时展示上一条修改的数据
this.form.resetFields()
this.setState({
showStatus:0
})
}
//执行添加分类:
addCate= async ()=>{
//1.获取表单数据
const {parentId,categoryName}=this.form.getFieldsValue()
//2.清除表单数据
this.form.resetFields()
const result = await reqAddCategory(parentId,categoryName)
if(result.status===0){//3.如果添加成功:
// 【1】如果新添加的分类就是当前分类下的子分类(当前表单显示的parentId=状态中的parentId):
if(parentId===this.state.parentId){
//隐藏对话框,提示添加成功
this.setState({showStatus:0})
message.success('产品分类添加成功')
//重新加载请求并展示添加之后的产品分类
this.getCategorys()
}else if(parentId==='0'){//【2】如果添加的是一级分类(parentId===0),则需获取一级分类,但无需显示
//【3】正常要重新设置state里的parentId=0然后再请求一次,但这样会造成跳转到一级分类
//因此把parentId直接做为参数传到getCategorys()里,这样就不会跳转显示一级分类,还是在二级分类里了
this.getCategorys('0')
//隐藏对话框,提示添加成功
this.setState({showStatus:0})
message.success('产品分类添加成功')
}else{//否则(添加其它分类下的子分类)
message.error('不能添加其它分类的子分类!')
}
}else{//6.添加失败:
message.error('产品分类添加失败')
}
}
//执行修改分类(点对话框的ok按钮执行此函数)
updateCate= async ()=>{
//1.点ok后隐藏对话框
this.setState({showStatus:0})
//2.准备数据
const categoryId=this.categoryObj._id
//从子组件update-cate-form.jsx组件获取要修改的分类名
const categoryName=this.form.getFieldValue('categoryName') //取this的form对象
// console.log('categoryId:',categoryId)
// console.log('categoryName:',categoryName)
//重置所有表单数据,防止使用缓存,造成点其它条目时展示上一条修改的数据
this.form.resetFields()
//3.发送请求更新分类
const result = await reqUpdateCategory({categoryId,categoryName})
if(result.status===0){
message.success('产品分类修改名称成功')
//4.重新显示修改名称后的分类列表
this.getCategorys()
}else{
message.error('产品分类修改名称失败')
}
}
// 页面完成加载后运行,用于异步加载等函数存放
componentDidMount(){
this.getCategorys() //获取表格数据源
}
// 页面将要加载运行:用于页面渲染前的数据准备
componentWillMount(){
this.initColumn() //准备表格列名相关数据
//this.addCate('5e41578325a557082c18f43b','洗衣机')
}
render(){
// 对state里数据解构:
const {categorys,subCategorys, parentId,parentName,loading,showStatus}=this.state
//把4步收到的参数赋值给categoryObj
const categoryOjb = this.categoryObj || {} // 如果还没有,则指定一个空对象
//卡片标题,如果是一及分类显示 一级分类列表,否则显示一级分类+链接+对应的一级分类名
const title= parentId==='0'?'一级分类列表':(
<span>
<LinkButton onClick={this.showCategorys}>一级分类列表</LinkButton> >>
<span>{parentName}</span>
</span>
)
//卡片右侧添加按键:添加监听
const extra=(
<Button type='primary' onClick={this.showAddCate}>
<Icon type='plus'/>
添加
</Button>
)
return(
<div className='category'>
{/*卡片样式组件*/}
<Card title={title} extra={extra} >
{/*
表格组件、边框、key为数据源的_id、
数据源、如果parentId为0设置一级分类列表为数据源、否则二级分类为列表源
列名定义、
一页显示数据条数,显示快速跳转
*/}
<Table
bordered
rowKey='_id'
dataSource={parentId==='0'? categorys:subCategorys}
columns={this.columns}
loading={loading}
pagination={{defaultPageSize: 5, showQuickJumper: true}}
/>
{/*添加对话框:0:都不显示,1:显示添加分类,2:显示更新分类
添加监听函数:addCate,updateCate,handleCancel
使用<AddCateForm组件
*/}
<Modal
title="添加分类"
visible={showStatus===1}
onOk={this.addCate}
onCancel={this.handleCancel}
>
{/**把categorys,和parentId、接收子组件from对象的函数、传到子组件add-cate-form.jsx里面 */}
<AddCateForm
categorys={categorys}
parentId={parentId}
setForm={(form)=>{this.form=form}}
/>
</Modal>
{/*
在updateCateForm组件加一个参数categoryName用于传给子组件,
实现更新时显示当前条目的产品分类名称
转到update-cate-form.jsx内接收传过来的参数categoryName
onOk点执行updateCate函数执行分类名修改
*/}
<Modal
title="修改分类"
visible={showStatus===2}
onOk={this.updateCate}
onCancel={this.handleCancel}
>
{/*接收子组件传来的form对象(向子组件传递带参数的函数,子组件调用它,再把from对象通过参数传回来)
子组件把form对象传来之前,将其赋值到this.from里
下接update-cate-form.jsx*/}
<UpdateCateForm
categoryName={categoryOjb.name}
setForm={(form)=>{this.form=form}}
/>
</Modal>
</Card>
</div>
)
}
}6.4添加表单验证:更新表单验证
antd表单及规则编写
【1】在字段装饰器加入规则【2】到父组件内写验证
1
2
3
4
5
6
7
8
9
10
11
12
13
14<Item>
<span>添加子分类:</span>
{
getFieldDecorator('categoryName',{
//【1】在字段装饰器加入规则【2】到父组件内写验证
rules:[
{required:true,message:'分类名称必须输入'}
]
})(
<Input type='text' placeholder='请输入子分类名称' />
)
}
</Item>表单验证函数
1 | //antd的表单验证函数结构 |
表单验证完整函数
1 | //执行添加分类: |
6.5更新产品分类的表单验证
表单部分update-cate-form.jsx
1 | <Item> |
验证部分category/index.jsx:
1 | //执行修改分类(点对话框的ok按钮执行此函数) |
6.4-6.5完整代码
index.jsx
1 | import React,{Component} from 'react' |
update-cate-fomr.jsx
1 | import React,{Component} from 'react' |
add-cate-form.jsx
1 | import React,{Component} from 'react' |