一、静态页面
目录结构
F:\Test\react-demo\admin-client\src\pages\admin\category
1 2 3 4 5 6
| 1 add-cate-form.jsx
2 index.jsx
3 index.less
4 update-cate-form.jsx
5
6 |
1. pages/category/index.jsx
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
| 1import React,{Component} from 'react'
2import {
3 Button,
4 Card, //引入卡片
5 Table, //引入表格
6 Icon, } from 'antd';
7import LinkButton from '../../../components/link-button' //引入自定义的链接样式按钮组件
8
9export default class Category extends Component{
10 state={}
11
12 render(){
13 //卡片标题
14 const title='产品分类管理'
15 //卡片右侧添加按键
16 const extra=(
17 <Button type='primary'>
18 <Icon type='plus'/>
19 添加
20 </Button>
21 )
22
23 // 表格数据源示例
24 const dataSource = [
25 {
26 "parentId": "0",
27 "_id": "5c2ed631f352726338607046",
28 "name": "分类001",
29 "__v": 0
30 },
31 {
32 "parentId": "0",
33 "_id": "5c2ed647f352726338607047",
34 "name": "分类2",
35 "__v": 0
36 },
37 {
38 "parentId": "0",
39 "_id": "5c2ed64cf352726338607048",
40 "name": "1分类3",
41 "__v": 0
42 }
43 ];
44
45 //表格列名
46 const columns = [
47 {
48 title: '分类名',
49 dataIndex: 'name',
50 key: 'name',
51 },
52 {
53 title: '操作',
54 width:'29%',
55 render: () => ( //向操作列所有行输出修改及查看分类两个按钮
56 <span>
57 <LinkButton>修改分类</LinkButton>
58 <LinkButton>查看子分类</LinkButton>
59 </span>
60 ),
61 },
62
63 ];
64
65 return(
66 <div className='category'>
67 {/*卡片样式组件*/}
68 <Card title={title} extra={extra} >
69 {/*表格组件、边框、key为数据源的_id、数据源、列名定义*/}
70 <Table
71 bordered
72 rowKey='_id'
73 dataSource={dataSource}
74 columns={columns} />
75 </Card>
76 </div>
77 )
78 }
79}
80
81 |

二、动态:产品分类数据请求
1.编写产品分类相关接口src/api/index.js
【1】获取产品一级/二级分类列表接口
【2】添加产品分类接口
【3】修改产品分类接口
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
| 1import ajax from './ajax'
2import jsonp from 'jsonp'
3import {message} from 'antd' //借用antd返回信息组件
4// const BASE = 'http://localhost:5000'
5const BASE = ''
6
7//导出一个函数,第1种写法
8//登录接口函数
9// export function reqLogin(username,password){
10// return ajax('login',{username,password},'POST')
11// }
12
13//导出一个函数,第2种写法
14// 登录接口函数
15export const reqLogin=(username,password)=>ajax(BASE+'login',{username,password},'POST')
16
17
18//【1】获取产品一级/二级分类列表接口
19export const reqCategorys=(parentId)=>ajax(BASE+'/manage/category/list',{parentId})
20//【2】添加产品分类接口
21export const reqAddCategory=(parentId,categoryName)=>ajax(BASE+'/manage/category/add',{parentId,categoryName},'POST')
22//【3】修改产品分类接口
23export const reqUpdateCategory=({parentId,categoryName})=>ajax(BASE+'/manage/category/update',{parentId,categoryName},'POST')
24
25
26// 天气接口
27export const reqWeather=(city) => {
28 const url = `http://api.map.baidu.com/telematics/v3/weather?location=${city}&output=json&ak=3p49MVra6urFRGOT9s8UBWr2`
29 //返回一个promise函数
30 return new Promise((resolve,reject) => {
31 //发送一个jsonp请求
32 jsonp(url,{},(err,data) => {
33 //输出请求的数据到控制台
34 console.log('jsonp()', err, data)
35 //如果请求成功
36 if(!err && data.status==='success'){
37 //从数据中解构取出图片、天气
38 const {dayPictureUrl,weather}=data.results[0].weather_data[0]
39 //异步返回图片、天气给调用函数者
40 resolve({dayPictureUrl,weather})
41 }else{//如果请求失败
42 message.error('天气信息获取失败')
43 }
44 })
45 })
46}
47//reqWeather('上海')
48
49 |
2. 获取数据category/index.jsx
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
| 1import React,{Component} from 'react'
2import './index.less'
3import {
4 Button,
5 Card,
6 Table,
7 Icon,
8 message,} from 'antd';
9import LinkButton from '../../../components/link-button'
10import {reqCategorys} from '../../../api/' //【1】获取api接口函数
11
12export default class Category extends Component{
13 state={
14 categorys:[] //【2】存放api接口获取的分类列表
15 }
16
17 //【3】异步请求一级分类列表
18 getCategorys = async (parentId)=>{
19 const result=await reqCategorys('0') //请求分类数据并赋值给result
20 if(result.status===0){ //如果返回的status=0,说明返回成功,执行:
21 const categorys=result.data //把返回数据赋值给categorys
22 console.log(result.data) //测试输出返回的数据
23 this.setState({
24 categorys //把返回的数据赋值给state里
25 })
26 }else{
27 message.error('获取分类失败')
28 }
29 }
30
31 //【4】初始化表格column列名函数
32 initColumn=()=>{
33 //表格列名
34 this.columns = [
35 {
36 title: '分类名子',
37 key: 'name',
38 dataIndex: 'name',
39 },
40 {
41 title: '操作',
42 width:'29%',
43 render: () => (
44 <span>
45 <LinkButton>修改分类</LinkButton>
46 <LinkButton>查看子分类</LinkButton>
47 </span>
48 ),
49 },
50
51 ];
52 }
53
54 // 【5】页面完成加载后运行,用于异步加载等函数存放
55 componentDidMount(){
56 this.getCategorys() //获取表格数据源
57 }
58
59 // 【6】页面将要加载运行:用于页面渲染前的数据准备
60 componentWillMount(){
61 this.initColumn() //准备表格列名相关数据
62 }
63
64
65
66 render(){
67 //卡片标题
68 const title='产品分类管理'
69 //卡片右侧添加按键
70 const extra=(
71 <Button type='primary'>
72 <Icon type='plus'/>
73 添加
74 </Button>
75 )
76
77 // 【7】对state里数据解构
78 const {categorys}=this.state
79
80 return(
81 <div className='category'>
82 {/*卡片样式组件*/}
83 <Card title={title} extra={extra} >
84 {/*
85 【8】表格组件、边框、key为数据源的_id、数据源、列名定义
86 */}
87 <Table
88 bordered
89 rowKey='_id'
90 dataSource={categorys}
91 columns={this.columns} />
92 </Card>
93 </div>
94 )
95 }
96}
97
98 |
效果同一.1
3. 优化:加载数据动画、分页显示
【1】控制是否显示加载动画
【2】设置加载中动画状态显示
【3】数据加载完成,取消loading动画显示
【4】对state里数据解构
【5】分页配置:每页显示数量,显示快速跳转
【6】加载动画、
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
| 1import React,{Component} from 'react'
2import './index.less'
3import {
4 Button,
5 Card,
6 Table,
7 Icon,
8 message,} from 'antd';
9import LinkButton from '../../../components/link-button'
10import {reqCategorys} from '../../../api/' //获取api接口函数
11
12export default class Category extends Component{
13 state={
14 loading:false, //【1】控制是否显示加载动画
15 categorys:[] //存放api接口获取的分类列表
16 }
17
18 //异步请求一级分类列表
19 getCategorys = async (parentId)=>{
20 this.setState({loading:true}) //【2】设置加载中动画状态显示
21 const result=await reqCategorys('0') //请求分类数据并赋值给result
22 if(result.status===0){ //如果返回的status=0,说明返回成功,执行:
23 const categorys=result.data //把返回数据赋值给categorys
24 console.log(result.data) //测试输出返回的数据
25 this.setState({
26 categorys, //把返回的数据赋值给state里
27 loading:false, //【3】数据加载完成,取消loading动画显示
28 })
29 }else{
30 message.error('获取分类失败')
31 }
32 }
33
34 //初始化表格column列名函数
35 initColumn=()=>{
36 //表格列名
37 this.columns = [
38 {
39 title: '分类名子',
40 key: 'name',
41 dataIndex: 'name',
42 },
43 {
44 title: '操作',
45 width:'29%',
46 render: () => (
47 <span>
48 <LinkButton>修改分类</LinkButton>
49 <LinkButton>查看子分类</LinkButton>
50 </span>
51 ),
52 },
53 ];
54 }
55
56 // 页面完成加载后运行,用于异步加载等函数存放
57 componentDidMount(){
58 this.getCategorys() //获取表格数据源
59 }
60
61 // 页面将要加载运行:用于页面渲染前的数据准备
62 componentWillMount(){
63 this.initColumn() //准备表格列名相关数据
64 }
65
66
67
68 render(){
69 //卡片标题
70 const title='产品分类管理'
71 //卡片右侧添加按键
72 const extra=(
73 <Button type='primary'>
74 <Icon type='plus'/>
75 添加
76 </Button>
77 )
78
79 // 【4】对state里数据解构
80 const {categorys,loading}=this.state
81
82 return(
83 <div className='category'>
84 {/*卡片样式组件*/}
85 <Card title={title} extra={extra} >
86 {/*
87 表格组件、边框、key为数据源的_id、
88 数据源、列名定义、
89 【5】分页配置:每页显示数量,显示快速跳转
90 【6】加载动画、
91 */}
92 <Table
93 bordered
94 rowKey='_id'
95 dataSource={categorys}
96 columns={this.columns}
97 loading={loading}
98 pagination={{defaultPageSize: 5, showQuickJumper: true}}
99 />
100 </Card>
101 </div>
102 )
103 }
104}
105
106 |
效果:加载时显示加载中动画、每页显示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 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
| 1import React,{Component} from 'react'
2import './index.less'
3import {
4 Button,
5 Card,
6 Table,
7 Icon,
8 message,} from 'antd';
9import LinkButton from '../../../components/link-button'
10import {reqCategorys,reqAddCategory} from '../../../api/' //获取api接口函数
11
12export default class Category extends Component{
13 state={
14 loading:false, //控制是否显示加载动画
15 parentId:'0', //【1】初始为0即请求一级产品分类列表
16 categorys:[], //存放api接口获取的分类列表
17 parentName:'', //【2】当前子分类的对应父分类名
18 subCategorys:[], //【3】子分类列表数据
19
20 }
21
22
23 //异步请求一级分类列表
24 getCategorys = async (parentId)=>{
25 this.setState({loading:true}) //设置加载中动画状态显示
26 parentId=parentId || this.state.parentId //【4】parentId等于传进来的参数或state里的值
27 const result=await reqCategorys(parentId) //【5】把0改为从state内动态获取,请求分类数据并赋值给result
28 if(result.status===0){ //如果返回的status=0,说明返回成功,执行:
29 console.log(result.data) //测试输出返回的数据
30 const categorys=result.data //把返回数据赋值给categorys
31
32 //【6】如果parentId=0则是一级列表,执行:
33 if(parentId==='0'){
34 this.setState({
35 categorys, //(因为名称和state标签名相同,所以用简写)把返回的一级产品分类数据,赋值给state里
36 loading:false, //数据加载完成,取消loading动画显示
37 })
38 }else{//【7】否则是二级列表,执行:
39 this.setState({
40 subCategorys:categorys, //把返回的二级产品分类数据,赋值给state里
41 loading:false, //数据加载完成,取消loading动画显示
42 })
43 }
44
45 }else{
46 message.error('获取分类列表失败')
47 }
48 }
49
50 //【10】显示一级分类对应二级产品分类函数
51 showSubCategory=(category)=>{
52 //【11】先更新状state的parentId为对应新分类的id
53 this.setState({
54 parentId:category._id,
55 parentName:category.name
56 },()=>{/*【12】setState是异步执行,并不会马上更新完状态,
57 因此需在其内部写(在状态更新且重新render()后执行)*/
58 console.log('parentId',this.state.parentId)
59 this.getCategorys()//获取二级分类列表
60 })
61
62 }
63 //【21】显示一级分类函数,设置id状态即可
64 showCategorys=()=>{
65 this.setState({
66 parentId:'0',
67 parentName:'',
68 subCategorys:[],
69 })
70 }
71 //初始化表格column列名函数
72 initColumn=()=>{
73 //表格列名
74 this.columns = [
75 {
76 title: '分类名',
77 key: 'name',
78 dataIndex: 'name',
79 },
80 {
81 title: '操作',
82 width:'29%',
83 render: (categoryObj) => (//【9.0】参数:当前条目的数据对象,返回需要显示的界面标签
84 <span>
85 <LinkButton>修改分类</LinkButton>
86 {/*
87 【9.1】添加事件监听点击时调用显示函数
88 因为如果加括号及参数就会自动执行函数,而不是点击后才执行,所以用一个匿名函数把它包起来
89 如果parentId=0即是父级列表则显示查看子分类按钮,否则什么也不显示
90 */}
91 {this.state.parentId==='0'?<LinkButton onClick={()=>this.showSubCategory(categoryOjb)}>查看子分类</LinkButton>:null}
92 </span>
93 ),
94 },
95
96 ];
97 }
98
99 //添加分类
100 addCate= async (parentId,categoryName)=>{
101 const result = await reqAddCategory(parentId,categoryName)
102 if(result.status===0){
103 message.success('分类数据添加成功')
104 }else{
105 message.error('添加分类失败')
106 }
107 }
108
109 // 页面完成加载后运行,用于异步加载等函数存放
110 componentDidMount(){
111 this.getCategorys() //获取表格数据源
112 }
113
114 // 页面将要加载运行:用于页面渲染前的数据准备
115 componentWillMount(){
116 this.initColumn() //准备表格列名相关数据
117 //this.addCate('5e41578325a557082c18f43b','洗衣机')
118 }
119
120 render(){
121 // 对state里数据解构
122 const {categorys,subCategorys, parentId,parentName,loading}=this.state
123
124 //【20】卡片标题,如果是一及分类显示 一级分类列表,否则显示一级分类+链接+对应的一级分类名
125 const title= parentId==='0'?'一级分类列表':(
126 <span>
127 <LinkButton onClick={this.showCategorys}>一级分类列表</LinkButton> >>
128 <span>{parentName}</span>
129 </span>
130 )
131 //卡片右侧添加按键
132 const extra=(
133 <Button type='primary'>
134 <Icon type='plus'/>
135 添加
136 </Button>
137 )
138
139
140
141 return(
142 <div className='category'>
143 {/*卡片样式组件*/}
144 <Card title={title} extra={extra} >
145 {/*
146 表格组件、边框、key为数据源的_id、
147 【8】数据源、如果parentId为0设置一级分类列表为数据源、否则二级分类为列表源
148 列名定义、
149 一页显示数据条数,显示快速跳转
150 */}
151 <Table
152 bordered
153 rowKey='_id'
154 dataSource={parentId==='0'? categorys:subCategorys}
155 columns={this.columns}
156 loading={loading}
157 pagination={{defaultPageSize: 5, showQuickJumper: true}}
158 />
159 </Card>
160 </div>
161 )
162 }
163}
164
165 |

四、添加分类、更新分类基础布局
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 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
| 1import React,{Component} from 'react'
2import './index.less'
3import {
4 Button,
5 Card,
6 Table,
7 Icon,
8 Modal, //【1】引入对话框
9 message,} from 'antd';
10import LinkButton from '../../../components/link-button'
11import {reqCategorys,reqAddCategory} from '../../../api/' //获取api接口函数
12
13export default class Category extends Component{
14 state={
15 loading:false, //控制是否显示加载动画
16 parentId:'0', //初始为0即请求一级产品分类列表
17 categorys:[], //存放api接口获取的分类列表
18 parentName:'', //当前子分类的对应父分类名
19 subCategorys:[], //子分类列表数据
20 showStatus:0, //【2】添加分类、更新分类显示状态,0:都不显示,1:显示添加,2:显示更新
21 }
22
23 //异步请求一级分类列表
24 getCategorys = async (parentId)=>{
25 this.setState({loading:true}) //设置加载中动画状态显示
26 parentId=parentId || this.state.parentId //parentId等于传进来的参数或state里的值
27 const result=await reqCategorys(parentId) //把0改为从state内动态获取,请求分类数据并赋值给result
28 if(result.status===0){ //如果返回的status=0,说明返回成功,执行:
29 console.log(result.data) //测试输出返回的数据
30 const categorys=result.data //把返回数据赋值给categorys
31
32 //如果parentId=0则是一级列表,执行:
33 if(parentId==='0'){
34 this.setState({
35 categorys, //(因为名称和state标签名相同,所以用简写)把返回的一级产品分类数据,赋值给state里
36 loading:false, //数据加载完成,取消loading动画显示
37 })
38 }else{//否则是二级列表,执行:
39 this.setState({
40 subCategorys:categorys, //把返回的二级产品分类数据,赋值给state里
41 loading:false, //数据加载完成,取消loading动画显示
42 })
43 }
44
45 }else{
46 message.error('获取分类列表失败')
47 }
48 }
49
50 //显示一级分类对应二级产品分类函数
51 showSubCategory=(category)=>{
52 //先更新状state的parentId为对应新分类的id
53 this.setState({
54 parentId:category._id,
55 parentName:category.name
56 },()=>{/*setState是异步执行,并不会马上更新完状态,
57 因此需在其内部写(在状态更新且重新render()后执行)*/
58 console.log('parentId',this.state.parentId)
59 this.getCategorys()//获取二级分类列表
60 })
61
62 }
63
64 //显示一级分类函数,设置id状态即可
65 showCategorys=()=>{
66 this.setState({
67 parentId:'0',
68 parentName:'',
69 subCategorys:[],
70 })
71 }
72
73 //初始化表格column列名函数
74 initColumn=()=>{
75 //表格列名
76 this.columns = [
77 {
78 title: '分类名',
79 key: 'name',
80 dataIndex: 'name',
81 },
82 {
83 title: '操作',
84 width:'29%',
85 render: (categoryObj) => (//参数:当前条目数据对象,用于返回需要显示的界面标签
86 <span>
87 {/*【9】添加监听showUpdateCate */}
88 <LinkButton onClick={this.showUpdateCate}>修改分类</LinkButton>
89 {/*
90 添加事件监听点击时调用显示函数
91 因为如果加括号及参数就会自动执行函数,而不是点击后才执行,所以用一个匿名函数把它包起来
92 如果parentId=0即是父级列表则显示查看子分类按钮,否则什么也不显示
93 */}
94 {this.state.parentId==='0'?<LinkButton onClick={()=>this.showSubCategory(categoryOjb)}>查看子分类</LinkButton>:null}
95 </span>
96 ),
97 },
98
99 ];
100 }
101
102
103 //【6】显示添加分类
104 showAddCate=()=>{
105 this.setState({
106 showStatus:1
107 })
108 }
109 //【7】显示更新分类showUp,
110 showUpdateCate=()=>{
111 this.setState({
112 showStatus:2
113 })
114 }
115 //【8】取消对话框函数handleCancel
116 handleCancel=()=>{
117 this.setState({
118 showStatus:0
119 })
120 }
121
122 // 页面完成加载后运行,用于异步加载等函数存放
123 componentDidMount(){
124 this.getCategorys() //获取表格数据源
125 }
126
127 // 页面将要加载运行:用于页面渲染前的数据准备
128 componentWillMount(){
129 this.initColumn() //准备表格列名相关数据
130 //this.addCate('5e41578325a557082c18f43b','洗衣机')
131 }
132
133 render(){
134 // 【3】对state里数据解构:
135 const {categorys,subCategorys, parentId,parentName,loading,showStatus}=this.state
136
137 //卡片标题,如果是一及分类显示 一级分类列表,否则显示一级分类+链接+对应的一级分类名
138 const title= parentId==='0'?'一级分类列表':(
139 <span>
140 <LinkButton onClick={this.showCategorys}>一级分类列表</LinkButton> >>
141 <span>{parentName}</span>
142 </span>
143 )
144 //【10】卡片右侧添加按键:添加监听
145 const extra=(
146 <Button type='primary' onClick={this.addCate}>
147 <Icon type='plus'/>
148 添加
149 </Button>
150 )
151
152 return(
153 <div className='category'>
154 {/*卡片样式组件*/}
155 <Card title={title} extra={extra} >
156 {/*
157 表格组件、边框、key为数据源的_id、
158 数据源、如果parentId为0设置一级分类列表为数据源、否则二级分类为列表源
159 列名定义、
160 一页显示数据条数,显示快速跳转
161 */}
162 <Table
163 bordered
164 rowKey='_id'
165 dataSource={parentId==='0'? categorys:subCategorys}
166 columns={this.columns}
167 loading={loading}
168 pagination={{defaultPageSize: 5, showQuickJumper: true}}
169 />
170
171
172 {/*【4】添加对话框:0:都不显示,1:显示添加分类,2:显示更新分类
173 【5】添加监听函数:addCate,updateCate,handleCancel */}
174 <Modal
175 title="添加分类"
176 visible={showStatus===1}
177 onOk={this.addCate}
178 onCancel={this.handleCancel}
179 >
180 <p>添加分类</p>
181 </Modal>
182
183 <Modal
184 title="修改分类"
185 visible={showStatus===2}
186 onOk={this.updateCate}
187 onCancel={this.handleCancel}
188 >
189 <p>修改分类</p>
190 </Modal>
191
192 </Card>
193 </div>
194 )
195 }
196}
197
198 |
4.2编写添加分类界面pages/category/add-cate-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
| 1import React,{Component} from 'react'
2import {
3 Form,
4 Select,
5 Input
6} from 'antd'
7
8const Item=Form.Item
9const Option=Select.Option
10
11class AddCateForm extends Component{
12
13 render(){
14 return(
15 <Form>
16 <Item>
17 <span>所属分类:</span>
18 <Select>
19 <Option value='1'>一级分类</Option>
20 </Select>
21 </Item>
22
23 <Item>
24 <span>添加子分类:</span>
25 <Input type='text' placeholder='请输入子分类名称' />
26 </Item>
27
28 </Form>
29 )
30 }
31}
32export default AddCateForm;
33
34 |
pages/category/index.jsx引入刚写的组件
【20】添加分类表单
【21】使用<AddCateForm组件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| 1import AddCateForm from './add-cate-form';//【20】添加分类表单
2
3......
4
5{/*添加对话框:0:都不显示,1:显示添加分类,2:显示更新分类
6 添加监听函数:addCate,updateCate,handleCancel
7 【21】使用<AddCateForm组件
8 */}
9 <Modal
10 title="添加分类"
11 visible={showStatus===1}
12 onOk={this.addCate}
13 onCancel={this.handleCancel}
14 >
15 <AddCateForm />
16 </Modal>
17
18 |
4.4 表单返回数值获取知识点
官网文档:https://ant.design/components/form-cn/\#Form.create(options)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| 1improt {Form} from 'antd'
2const {categorys, parentId} = this.props
3const { getFieldDecorator } = this.props.form
4
5{
6 getFieldDecorator('parentId',{
7 initialValue:parentId
8 })(//要获取表单值的标签)
9}
10
11
12
13{
14 getFieldDecorator('categoryName',{
15 rules:[
16 {required:true,message:'分类名称必须输入'}
17 ]
18 })(
19 <Input type='text' placeholder='请输入子分类名称' />
20 )
21}
22exprot default Form.create()(组件名)
23
24 |
完整代码add-cate-form.jsx
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
| 1import React,{Component} from 'react'
2import {
3 Form,
4 Select,
5 Input
6} from 'antd'
7
8const Item=Form.Item
9const Option=Select.Option
10
11class AddCateForm extends Component{
12
13 render(){
14 const {categorys, parentId} = this.props
15 const { getFieldDecorator } = this.props.form
16 return(
17 <Form>
18 <Item>
19 <span>所属分类:</span>
20 {
21 getFieldDecorator('parentId',{
22 initialValue:parentId
23 })(
24 <Select>
25 <Option value='1'>一级分类</Option>
26 </Select>
27 )
28 }
29
30 </Item>
31
32 <Item>
33 <span>添加子分类:</span>
34 {
35 getFieldDecorator('categoryName',{
36 rules:[
37 {required:true,message:'分类名称必须输入'}
38 ]
39 })(
40
41 <Input type='text' placeholder='请输入子分类名称' />
42 )
43 }
44
45 </Item>
46
47 </Form>
48 )
49 }
50}
51export default Form.create()(AddCateForm);
52
53 |
4.5编写修改分类界面pages/category/update-cate-form.jsx
到此和4.4代码相同,换个类名即可
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
| 1import React,{Component} from 'react'
2import {
3 Form,
4 Select,
5 Input
6} from 'antd'
7
8const Item=Form.Item
9const Option=Select.Option
10
11class UpdateCateForm extends Component{
12
13 render(){
14 const {categorys, parentId} = this.props
15 const { getFieldDecorator } = this.props.form
16 return(
17 <Form>
18 <Item>
19 <span>所属分类:</span>
20 {
21 getFieldDecorator('parentId',{
22 initialValue:parentId
23 })(
24 <Select>
25 <Option value='1'>一级分类</Option>
26 </Select>
27 )
28 }
29
30 </Item>
31
32 <Item>
33 <span>添加子分类:</span>
34 {
35 getFieldDecorator('categoryName',{
36 rules:[
37 {required:true,message:'分类名称必须输入'}
38 ]
39 })(
40
41 <Input type='text' placeholder='请输入子分类名称' />
42 )
43 }
44
45 </Item>
46
47 </Form>
48 )
49 }
50}
51export default Form.create()(UpdateCateForm);
52
53 |

五、修改产品分类功能实现
1.点击修改分类时自动显示对应的分类名pages/category/index.jsx
【1】在updateCateForm组件加一个参数categoryName用于传给子组件, 实现更新时显示当前条目的产品分类名称
【2】把当前条目的数据对象传递给updateCate函数
【3】接收[2]传来的对应条目数据对象
【4】接收参数赋值到当前函数
【5】把4步收到的参数赋值给categoryObj
【6】转到update-cate-form.jsx内接收传过来的参数categoryName
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
| 1import React,{Component} from 'react'
2import './index.less'
3import {
4 Button,
5 Card,
6 Table,
7 Icon,
8 Modal, //引入对话框
9 message,} from 'antd';
10import LinkButton from '../../../components/link-button'
11import {reqCategorys,reqAddCategory} from '../../../api/' //获取api接口函数
12import AddCateForm from './add-cate-form'; //添加分类表单
13import UpdateCateForm from './update-cate-form'; //导入更新分类的表单
14
15export default class Category extends Component{
16 state={
17 loading:false, //控制是否显示加载动画
18 parentId:'0', //初始为0即请求一级产品分类列表
19 categorys:[], //存放api接口获取的分类列表
20 parentName:'', //当前子分类的对应父分类名
21 subCategorys:[], //子分类列表数据
22 showStatus:0, //添加分类、更新分类显示状态,0:都不显示,1:显示添加,2:显示更新
23 }
24
25
26 //异步请求一级分类列表
27 getCategorys = async (parentId)=>{
28 this.setState({loading:true}) //设置加载中动画状态显示
29 parentId=parentId || this.state.parentId //parentId等于传进来的参数或state里的值
30 const result=await reqCategorys(parentId) //把0改为从state内动态获取,请求分类数据并赋值给result
31 if(result.status===0){ //如果返回的status=0,说明返回成功,执行:
32 console.log(result.data) //测试输出返回的数据
33 const categorys=result.data //把返回数据赋值给categorys
34
35 //如果parentId=0则是一级列表,执行:
36 if(parentId==='0'){
37 this.setState({
38 categorys, //(因为名称和state标签名相同,所以用简写)把返回的一级产品分类数据,赋值给state里
39 loading:false, //数据加载完成,取消loading动画显示
40 })
41 }else{//否则是二级列表,执行:
42 this.setState({
43 subCategorys:categorys, //把返回的二级产品分类数据,赋值给state里
44 loading:false, //数据加载完成,取消loading动画显示
45 })
46 }
47
48 }else{
49 message.error('获取分类列表失败')
50 }
51 }
52
53 //显示一级分类对应二级产品分类函数
54 showSubCategory=(category)=>{
55 //先更新状state的parentId为对应新分类的id
56 this.setState({
57 parentId:category._id,
58 parentName:category.name
59 },()=>{/*setState是异步执行,并不会马上更新完状态,
60 因此需在其内部写(在状态更新且重新render()后执行)*/
61 console.log('parentId',this.state.parentId)
62 this.getCategorys()//获取二级分类列表
63 })
64
65 }
66
67 //显示一级分类函数,设置id状态即可
68 showCategorys=()=>{
69 this.setState({
70 parentId:'0',
71 parentName:'',
72 subCategorys:[],
73 })
74 }
75
76 //初始化表格column列名函数
77 initColumn=()=>{
78 //表格列名
79 this.columns = [
80 {
81 title: '分类名',
82 key: 'name',
83 dataIndex: 'name',
84 },
85 {
86 title: '操作',
87 width:'29%',
88 render: (categoryObj) => (//category代表当前条目对象(名字随意),用于返回需要显示的界面标签
89 <span>
90 {/*【2】把当前条目的数据对象传递给showUpdateCate函数 */}
91 <LinkButton onClick={()=>this.showUpdateCate(categoryObj)}>修改分类</LinkButton>
92 {/*
93 添加事件监听点击时调用显示函数
94 因为如果加括号及参数就会自动执行函数,而不是点击后才执行,所以用一个匿名函数把它包起来
95 如果parentId=0即是父级列表则显示查看子分类按钮,否则什么也不显示
96 */}
97 {this.state.parentId==='0'?<LinkButton onClick={()=>{this.showSubCategory(categoryObj)}}>查看子分类</LinkButton>:null}
98 </span>
99 ),
100 },
101
102 ];
103 }
104
105
106 //添加分类函数
107 addCate= async (parentId,categoryName)=>{
108 this.setState({
109 showStatus:1
110 })
111 // const result = await reqAddCategory(parentId,categoryName)
112 // if(result.status===0){
113 // message.success('分类数据添加成功')
114 // }else{
115 // message.error('添加分类失败')
116 // }
117 }
118
119 //更新分类函数showUpdateCate,【3】接收[2]传来的对应条目数据对象
120 showUpdateCate=(categoryObj)=>{
121 //【4】接收参数赋值到当前函数
122 this.categoryObj=categoryObj
123 this.setState({
124 showStatus:2
125 })
126 }
127
128 //取消对话框函数handleCancel
129 handleCancel=()=>{
130 this.setState({
131 showStatus:0
132 })
133 }
134
135 // 页面完成加载后运行,用于异步加载等函数存放
136 componentDidMount(){
137 this.getCategorys() //获取表格数据源
138 }
139
140 // 页面将要加载运行:用于页面渲染前的数据准备
141 componentWillMount(){
142 this.initColumn() //准备表格列名相关数据
143 //this.addCate('5e41578325a557082c18f43b','洗衣机')
144 }
145
146 render(){
147 // 对state里数据解构:
148 const {categorys,subCategorys, parentId,parentName,loading,showStatus}=this.state
149 //【5】把4步收到的参数赋值给categoryObj
150 const categoryOjb = this.categoryObj || {} // 如果还没有,则指定一个空对象
151
152 //卡片标题,如果是一及分类显示 一级分类列表,否则显示一级分类+链接+对应的一级分类名
153 const title= parentId==='0'?'一级分类列表':(
154 <span>
155 <LinkButton onClick={this.showCategorys}>一级分类列表</LinkButton> >>
156 <span>{parentName}</span>
157 </span>
158 )
159 //卡片右侧添加按键:添加监听
160 const extra=(
161 <Button type='primary' onClick={this.addCate}>
162 <Icon type='plus'/>
163 添加
164 </Button>
165 )
166
167 return(
168 <div className='category'>
169 {/*卡片样式组件*/}
170 <Card title={title} extra={extra} >
171 {/*
172 表格组件、边框、key为数据源的_id、
173 数据源、如果parentId为0设置一级分类列表为数据源、否则二级分类为列表源
174 列名定义、
175 一页显示数据条数,显示快速跳转
176 */}
177 <Table
178 bordered
179 rowKey='_id'
180 dataSource={parentId==='0'? categorys:subCategorys}
181 columns={this.columns}
182 loading={loading}
183 pagination={{defaultPageSize: 5, showQuickJumper: true}}
184 />
185
186
187 {/*添加对话框:0:都不显示,1:显示添加分类,2:显示更新分类
188 添加监听函数:addCate,updateCate,handleCancel
189 使用<AddCateForm组件
190
191 */}
192 <Modal
193 title="添加分类"
194 visible={showStatus===1}
195 onOk={this.addCate}
196 onCancel={this.handleCancel}
197 >
198 <AddCateForm />
199 </Modal>
200
201 {/*
202 【1】在updateCateForm组件加一个参数categoryName用于传给子组件,
203 实现更新时显示当前条目的产品分类名称
204 【6】转到update-cate-form.jsx内接收传过来的参数categoryName
205 */}
206 <Modal
207 title="修改分类"
208 visible={showStatus===2}
209 onOk={this.updateCate}
210 onCancel={this.handleCancel}
211 >
212 <UpdateCateForm categoryName={categoryOjb.name}/>
213 </Modal>
214
215 </Card>
216 </div>
217 )
218 }
219}
220
221 |
2.接收父组件传过来的属性值,实现显示对应条目的类名update-cate-from.jsx
【1】接收父组件传值组件
【2】把从父组件接收过来的属性参数接收过来
【3】把categoryName解构出来
【4】文本框默认值为父组件传过来的对应条目数据的名字
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
| 1import React,{Component} from 'react'
2import {
3 Form,
4 Select,
5 Input
6} from 'antd'
7import PropTypes from 'prop-types' //【1】接收父组件传值组件
8
9const Item=Form.Item
10const Option=Select.Option
11
12class UpdateCateForm extends Component{
13 //【2】把从父组件接收过来的属性参数接收过来
14 static propTypes={
15 categoryName:PropTypes.string.isRequired,
16 }
17
18 render(){
19 //【3】把categoryName解构出来
20 const {categoryName} = this.props
21 const { getFieldDecorator } = this.props.form
22 return(
23 <Form>
24 <Item>
25 {/**因为getFiledDecorator接收的标签必须为Form标签,因此span必须拿出来 */}
26 <span>修改分类名:</span>
27 {
28 getFieldDecorator('categoryName',{
29 //【4】文本框默认值为父组件传过来的对应条目数据的名字
30 initialValue:categoryName,
31 rules:[
32 {required:true,message:'分类名称必须输入'}
33 ]
34 })(
35
36 <Input type='text' placeholder='请输入子分类名称' />
37 )
38 }
39
40 </Item>
41
42 </Form>
43 )
44 }
45}
46export default Form.create()(UpdateCateForm);
47
48 |
效果:

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 259 260 261
| 1import React,{Component} from 'react'
2import './index.less'
3import {
4 Button,
5 Card,
6 Table,
7 Icon,
8 Modal, //引入对话框
9 message,} from 'antd';
10import LinkButton from '../../../components/link-button'
11import {reqCategorys,reqAddCategory,reqUpdateCategory} from '../../../api/' //获取api接口请求函数
12import AddCateForm from './add-cate-form'; //添加分类表单
13import UpdateCateForm from './update-cate-form'; //导入更新分类的表单
14
15export default class Category extends Component{
16 state={
17 loading:false, //控制是否显示加载动画
18 parentId:'0', //初始为0即请求一级产品分类列表
19 categorys:[], //存放api接口获取的分类列表
20 parentName:'', //当前子分类的对应父分类名
21 subCategorys:[], //子分类列表数据
22 showStatus:0, //添加分类、更新分类显示状态,0:都不显示,1:显示添加,2:显示更新
23 }
24
25
26 //异步请求一级分类列表
27 getCategorys = async (parentId)=>{
28 this.setState({loading:true}) //设置加载中动画状态显示
29 parentId=parentId || this.state.parentId //parentId等于传进来的参数或state里的值
30 const result=await reqCategorys(parentId) //把0改为从state内动态获取,请求分类数据并赋值给result
31 if(result.status===0){ //如果返回的status=0,说明返回成功,执行:
32 console.log(result.data) //测试输出返回的数据
33 const categorys=result.data //把返回数据赋值给categorys
34
35 //如果parentId=0则是一级列表,执行:
36 if(parentId==='0'){
37 this.setState({
38 categorys, //(因为名称和state标签名相同,所以用简写)把返回的一级产品分类数据,赋值给state里
39 loading:false, //数据加载完成,取消loading动画显示
40 })
41 }else{//否则是二级列表,执行:
42 this.setState({
43 subCategorys:categorys, //把返回的二级产品分类数据,赋值给state里
44 loading:false, //数据加载完成,取消loading动画显示
45 })
46 }
47
48 }else{
49 message.error('获取分类列表失败')
50 }
51 }
52
53 //显示一级分类对应二级产品分类函数
54 showSubCategory=(category)=>{
55 //先更新状state的parentId为对应新分类的id
56 this.setState({
57 parentId:category._id,
58 parentName:category.name
59 },()=>{/*setState是异步执行,并不会马上更新完状态,
60 因此需在其内部写(在状态更新且重新render()后执行)*/
61 console.log('parentId',this.state.parentId)
62 this.getCategorys()//获取二级分类列表
63 })
64
65 }
66
67 //显示一级分类函数,设置id状态即可
68 showCategorys=()=>{
69 this.setState({
70 parentId:'0',
71 parentName:'',
72 subCategorys:[],
73 })
74 }
75
76 //初始化表格column列名函数
77 initColumn=()=>{
78 //表格列名
79 this.columns = [
80 {
81 title: '分类名',
82 key: 'name',
83 dataIndex: 'name',
84 },
85 {
86 title: '操作',
87 width:'29%',
88 render: (categoryObj) => (//category代表当前条目对象(名字随意),用于返回需要显示的界面标签
89 <span>
90 {/*把当前条目的数据对象传递给updateCate函数 */}
91 <LinkButton onClick={()=>this.showUpdateCate(categoryObj)}>修改分类</LinkButton>
92 {/*
93 添加事件监听点击时调用显示函数
94 因为如果加括号及参数就会自动执行函数,而不是点击后才执行,所以用一个匿名函数把它包起来
95 如果parentId=0即是父级列表则显示查看子分类按钮,否则什么也不显示
96 */}
97 {this.state.parentId==='0'?<LinkButton onClick={()=>{this.showSubCategory(categoryObj)}}>查看子分类</LinkButton>:null}
98 </span>
99 ),
100 },
101
102 ];
103 }
104
105
106 //显示添加分类函数
107 showAddCate= async (parentId,categoryName)=>{
108 this.setState({
109 showStatus:1
110 })
111 }
112
113 //更新分类函数updateCate,接收[2]传来的对应条目数据对象
114 showUpdateCate=(categoryObj)=>{
115 //接收参数赋值到当前函数
116 this.categoryObj=categoryObj
117 this.setState({
118 showStatus:2
119 })
120 }
121
122 //取消对话框函数handleCancel
123 handleCancel=()=>{
124 //【6】重置所有表单数据,防止上一条数据修改后点取消,下一条使用缓存,点其它条目时展示上一条修改的数据
125 this.form.resetFields()
126 this.setState({
127 showStatus:0
128 })
129 }
130
131
132 //执行添加分类
133 AddCate= async (parentId,categoryName)=>{
134
135 const result = await reqAddCategory(parentId,categoryName)
136 if(result.status===0){
137 message.success('产品分类添加成功')
138 }else{
139 message.error('产品分类添加失败')
140 }
141 }
142
143
144 //【1】执行修改分类(点对话框的ok按钮执行此函数)
145 updateCate= async ()=>{
146 //1.点ok后隐藏对话框
147 this.setState({showStatus:0})
148 //2.准备数据
149 const categoryId=this.categoryObj._id
150 //【2】从子组件update-cate-form.jsx组件获取要修改的分类名
151 const categoryName=this.form.getFieldValue('categoryName') //取this的form对象
152 // console.log('categoryId:',categoryId)
153 // console.log('categoryName:',categoryName)
154 //【5】重置所有表单数据,防止使用缓存,造成点其它条目时展示上一条修改的数据
155 this.form.resetFields()
156 //3.发送请求更新分类
157 const result = await reqUpdateCategory({categoryId,categoryName})
158
159 if(result.status===0){
160 message.success('产品分类修改名称成功')
161 //4.重新显示修改名称后的分类列表
162 this.getCategorys()
163 }else{
164 message.error('产品分类修改名称失败')
165 }
166 }
167
168 // 页面完成加载后运行,用于异步加载等函数存放
169 componentDidMount(){
170 this.getCategorys() //获取表格数据源
171 }
172
173 // 页面将要加载运行:用于页面渲染前的数据准备
174 componentWillMount(){
175 this.initColumn() //准备表格列名相关数据
176 //this.addCate('5e41578325a557082c18f43b','洗衣机')
177 }
178
179 render(){
180 // 对state里数据解构:
181 const {categorys,subCategorys, parentId,parentName,loading,showStatus}=this.state
182 //把4步收到的参数赋值给categoryObj
183 const categoryOjb = this.categoryObj || {} // 如果还没有,则指定一个空对象
184
185 //卡片标题,如果是一及分类显示 一级分类列表,否则显示一级分类+链接+对应的一级分类名
186 const title= parentId==='0'?'一级分类列表':(
187 <span>
188 <LinkButton onClick={this.showCategorys}>一级分类列表</LinkButton> >>
189 <span>{parentName}</span>
190 </span>
191 )
192 //卡片右侧添加按键:添加监听
193 const extra=(
194 <Button type='primary' onClick={this.showAddCate}>
195 <Icon type='plus'/>
196 添加
197 </Button>
198 )
199
200 return(
201 <div className='category'>
202 {/*卡片样式组件*/}
203 <Card title={title} extra={extra} >
204 {/*
205 表格组件、边框、key为数据源的_id、
206 数据源、如果parentId为0设置一级分类列表为数据源、否则二级分类为列表源
207 列名定义、
208 一页显示数据条数,显示快速跳转
209 */}
210 <Table
211 bordered
212 rowKey='_id'
213 dataSource={parentId==='0'? categorys:subCategorys}
214 columns={this.columns}
215 loading={loading}
216 pagination={{defaultPageSize: 5, showQuickJumper: true}}
217 />
218
219
220 {/*添加对话框:0:都不显示,1:显示添加分类,2:显示更新分类
221 添加监听函数:addCate,updateCate,handleCancel
222 使用<AddCateForm组件
223
224 */}
225 <Modal
226 title="添加分类"
227 visible={showStatus===1}
228 onOk={this.addCate}
229 onCancel={this.handleCancel}
230 >
231 <AddCateForm />
232 </Modal>
233
234 {/*
235 在updateCateForm组件加一个参数categoryName用于传给子组件,
236 实现更新时显示当前条目的产品分类名称
237 转到update-cate-form.jsx内接收传过来的参数categoryName
238 【0】onOk点执行updateCate函数执行分类名修改
239 */}
240 <Modal
241 title="修改分类"
242 visible={showStatus===2}
243 onOk={this.updateCate}
244 onCancel={this.handleCancel}
245 >
246 {/*【3】接收子组件传来的form对象(向子组件传递带参数的函数,子组件调用它,再把from对象通过参数传回来)
247 子组件把form对象传来之前,将其赋值到this.from里
248 【4】下接update-cate-form.jsx*/}
249 <UpdateCateForm
250 categoryName={categoryOjb.name}
251 setForm={(form)=>{this.form=form}}
252 />
253 </Modal>
254
255 </Card>
256 </div>
257 )
258 }
259}
260
261 |
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 68 69 70
| 1import React,{Component} from 'react'
2import {
3 Form,
4 Select,
5 Input
6} from 'antd'
7import PropTypes from 'prop-types' //接收父组件传值组件
8
9const Item=Form.Item
10const Option=Select.Option
11
12class UpdateCateForm extends Component{
13 //把从父组件接收过来的属性参数接收过来
14 static propTypes={
15 categoryName:PropTypes.string.isRequired,
16 //【1】设置setForm类型为函数且必须
17 setForm:PropTypes.func.isRequired,
18 }
19
20 //【2】在此组件渲染之前调用一次setForm函数,把form传到父组件去
21 componentWillMount(){
22 //将form对象通过setForm函数传给父组件
23 this.props.setForm(this.props.form)
24 }
25
26 render(){
27 //把categoryName解构出来
28 const {categoryName} = this.props
29 const { getFieldDecorator } = this.props.form
30 return(
31 <Form>
32 {/*<Item>
33 <span>所属分类:</span>
34 {
35 getFieldDecorator('parentId',{
36 initialValue:parentId
37 })(
38 <Select>
39 <Option value='1'>一级分类</Option>
40 </Select>
41 )
42 }
43
44 </Item>*/}
45
46 <Item>
47 {/**因为getFiledDecorator接收的标签必须为Form标签,因此span必须拿出来 */}
48 <span>修改分类名:</span>
49 {
50 getFieldDecorator('categoryName',{
51 //文本框默认值为父组件传过来的对应条目数据的名字
52 initialValue:categoryName,
53 rules:[
54 {required:true,message:'分类名称必须输入'}
55 ]
56 })(
57
58 <Input type='text' placeholder='请输入子分类名称' />
59 )
60 }
61
62 </Item>
63
64 </Form>
65 )
66 }
67}
68export default Form.create()(UpdateCateForm);
69
70 |
效果:同上,但修改一个条目后,再点下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 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
| 1import React,{Component} from 'react'
2import {
3 Form,
4 Select,
5 Input
6} from 'antd';
7import PropTypes from 'prop-types' //【1】引入父子传值模块
8
9const Item=Form.Item
10const Option=Select.Option
11
12class AddCateForm extends Component{
13 //【2】引入父组件的相关信息
14 static propTypes={
15 categorys:PropTypes.array.isRequired, //父组件的一级分类列表
16 parentId:PropTypes.string.isRequired, //父组件传过来的当前产品分类的parentId
17 setForm:PropTypes.func.isRequired,//用来接收父组件传过来的接收子组件form对象的函数
18 }
19 //【6】把当前组件的form作为参数运行一下父组件传过来的[接收子组件form对象函数],从而实现父组件也有form对象
20 componentWillMount(){
21 this.props.setForm(this.props.form)
22 }
23
24 render(){
25 //【3】到父组件category/index.jsx下把categorys[],parentId,from对象传过来
26 //【4】取出父组件传过来的categorys,parentId
27 const {categorys, parentId} = this.props
28 const { getFieldDecorator } = this.props.form
29 return(
30 <Form>
31 <Item>
32 <span>所属分类:</span>
33 {
34 /*【5】令inintalValue=parentId(实现在子分类点添加分类时一级分类自动显示对应分类)、
35 把一级分类动态写入(实现自动调取所有一级分类)、【6】回到父组件实现功能*/
36 getFieldDecorator('parentId',{
37 initialValue:parentId
38 })(
39 <Select>
40 <Option value='0'>一级分类</Option>
41 {
42 categorys.map(c=> <Option value={c._id}>{c.name}</Option>)
43 }
44 </Select>
45 )
46 }
47
48 </Item>
49
50 <Item>
51 <span>添加子分类:</span>
52 {
53 getFieldDecorator('categoryName',{
54 rules:[
55 {required:true,message:'分类名称必须输入'}
56 ]
57 })(
58
59 <Input type='text' placeholder='请输入子分类名称' />
60 )
61 }
62
63 </Item>
64
65 </Form>
66 )
67 }
68}
69export default Form.create()(AddCateForm);
70
71 |
6.2 添加分类功能实现:category/index.jsx
【1】把categorys,和parentId、接收子组件from对象的函数、传到子组件add-cate-form.jsx里面
【2】执行添加分类:
1.获取表单数据
2.清除表单数据
3.如果添加成功:
4.隐藏对话框,提示添加成功
5.重新加载产品分类
6.添加失败
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
| 1import React,{Component} from 'react'
2import './index.less'
3import {
4 Button,
5 Card,
6 Table,
7 Icon,
8 Modal, //引入对话框
9 message,} from 'antd';
10import LinkButton from '../../../components/link-button'
11import {reqCategorys,reqAddCategory,reqUpdateCategory} from '../../../api/' //获取api接口请求函数
12import AddCateForm from './add-cate-form'; //添加分类表单
13import UpdateCateForm from './update-cate-form'; //导入更新分类的表单
14
15export default class Category extends Component{
16 state={
17 loading:false, //控制是否显示加载动画
18 parentId:'0', //初始为0即请求一级产品分类列表
19 categorys:[], //存放api接口获取的分类列表
20 parentName:'', //当前子分类的对应父分类名
21 subCategorys:[], //子分类列表数据
22 showStatus:0, //添加分类、更新分类显示状态,0:都不显示,1:显示添加,2:显示更新
23 }
24
25
26 //异步请求一级分类列表
27 getCategorys = async (parentId)=>{
28 this.setState({loading:true}) //设置加载中动画状态显示
29 parentId=parentId || this.state.parentId //parentId等于传进来的参数或state里的值
30 const result=await reqCategorys(parentId) //把0改为从state内动态获取,请求分类数据并赋值给result
31 if(result.status===0){ //如果返回的status=0,说明返回成功,执行:
32 console.log(result.data) //测试输出返回的数据
33 const categorys=result.data //把返回数据赋值给categorys
34
35 //如果parentId=0则是一级列表,执行:
36 if(parentId==='0'){
37 this.setState({
38 categorys, //(因为名称和state标签名相同,所以用简写)把返回的一级产品分类数据,赋值给state里
39 loading:false, //数据加载完成,取消loading动画显示
40 })
41 }else{//否则是二级列表,执行:
42 this.setState({
43 subCategorys:categorys, //把返回的二级产品分类数据,赋值给state里
44 loading:false, //数据加载完成,取消loading动画显示
45 })
46 }
47
48 }else{
49 message.error('获取分类列表失败')
50 }
51 }
52
53 //显示一级分类对应二级产品分类函数
54 showSubCategory=(category)=>{
55 //先更新状state的parentId为对应新分类的id
56 this.setState({
57 parentId:category._id,
58 parentName:category.name
59 },()=>{/*setState是异步执行,并不会马上更新完状态,
60 因此需在其内部写(在状态更新且重新render()后执行)*/
61 console.log('parentId',this.state.parentId)
62 this.getCategorys()//获取二级分类列表
63 })
64
65 }
66
67 //显示一级分类函数,设置id状态即可
68 showCategorys=()=>{
69 this.setState({
70 parentId:'0',
71 parentName:'',
72 subCategorys:[],
73 })
74 }
75
76 //初始化表格column列名函数
77 initColumn=()=>{
78 //表格列名
79 this.columns = [
80 {
81 title: '分类名',
82 key: 'name',
83 dataIndex: 'name',
84 },
85 {
86 title: '操作',
87 width:'29%',
88 render: (categoryObj) => (//category代表当前条目对象(名字随意),用于返回需要显示的界面标签
89 <span>
90 {/*把当前条目的数据对象传递给updateCate函数 */}
91 <LinkButton onClick={()=>this.showUpdateCate(categoryObj)}>修改分类</LinkButton>
92 {/*
93 添加事件监听点击时调用显示函数
94 因为如果加括号及参数就会自动执行函数,而不是点击后才执行,所以用一个匿名函数把它包起来
95 如果parentId=0即是父级列表则显示查看子分类按钮,否则什么也不显示
96 */}
97 {this.state.parentId==='0'?<LinkButton onClick={()=>{this.showSubCategory(categoryObj)}}>查看子分类</LinkButton>:null}
98 </span>
99 ),
100 },
101
102 ];
103 }
104
105
106 //显示添加分类函数
107 showAddCate= async (parentId,categoryName)=>{
108 this.setState({
109 showStatus:1
110 })
111 }
112
113 //更新分类函数updateCate,接收[2]传来的对应条目数据对象
114 showUpdateCate=(categoryObj)=>{
115 //接收参数赋值到当前函数
116 this.categoryObj=categoryObj
117 this.setState({
118 showStatus:2
119 })
120 }
121
122 //取消对话框函数handleCancel
123 handleCancel=()=>{
124 //重置所有表单数据,防止上一条数据修改后点取消,下一条使用缓存,点其它条目时展示上一条修改的数据
125 this.form.resetFields()
126 this.setState({
127 showStatus:0
128 })
129 }
130
131
132 //【2】执行添加分类:
133 addCate= async ()=>{
134 //1.获取表单数据
135 const {parentId,categoryName}=this.form.getFieldsValue()
136 //2.清除表单数据
137 this.form.resetFields()
138 const result = await reqAddCategory(parentId,categoryName)
139 if(result.status===0){//3.如果添加成功:
140 //4.隐藏对话框,提示添加成功
141 this.setState({showStatus:0})
142 message.success('产品分类添加成功')
143 //5.重新加载产品分类
144 this.getCategorys()
145 }else{
146 message.error('产品分类添加失败')
147 }
148 }
149
150
151 //执行修改分类(点对话框的ok按钮执行此函数)
152 updateCate= async ()=>{
153 //1.点ok后隐藏对话框
154 this.setState({showStatus:0})
155 //2.准备数据
156 const categoryId=this.categoryObj._id
157 //从子组件update-cate-form.jsx组件获取要修改的分类名
158 const categoryName=this.form.getFieldValue('categoryName') //取this的form对象
159 // console.log('categoryId:',categoryId)
160 // console.log('categoryName:',categoryName)
161 //重置所有表单数据,防止使用缓存,造成点其它条目时展示上一条修改的数据
162 this.form.resetFields()
163 //3.发送请求更新分类
164 const result = await reqUpdateCategory({categoryId,categoryName})
165
166 if(result.status===0){
167 message.success('产品分类修改名称成功')
168 //4.重新显示修改名称后的分类列表
169 this.getCategorys()
170 }else{
171 message.error('产品分类修改名称失败')
172 }
173 }
174
175 // 页面完成加载后运行,用于异步加载等函数存放
176 componentDidMount(){
177 this.getCategorys() //获取表格数据源
178 }
179
180 // 页面将要加载运行:用于页面渲染前的数据准备
181 componentWillMount(){
182 this.initColumn() //准备表格列名相关数据
183 //this.addCate('5e41578325a557082c18f43b','洗衣机')
184 }
185
186 render(){
187 // 对state里数据解构:
188 const {categorys,subCategorys, parentId,parentName,loading,showStatus}=this.state
189 //把4步收到的参数赋值给categoryObj
190 const categoryOjb = this.categoryObj || {} // 如果还没有,则指定一个空对象
191
192 //卡片标题,如果是一及分类显示 一级分类列表,否则显示一级分类+链接+对应的一级分类名
193 const title= parentId==='0'?'一级分类列表':(
194 <span>
195 <LinkButton onClick={this.showCategorys}>一级分类列表</LinkButton> >>
196 <span>{parentName}</span>
197 </span>
198 )
199 //卡片右侧添加按键:添加监听
200 const extra=(
201 <Button type='primary' onClick={this.showAddCate}>
202 <Icon type='plus'/>
203 添加
204 </Button>
205 )
206
207 return(
208 <div className='category'>
209 {/*卡片样式组件*/}
210 <Card title={title} extra={extra} >
211 {/*
212 表格组件、边框、key为数据源的_id、
213 数据源、如果parentId为0设置一级分类列表为数据源、否则二级分类为列表源
214 列名定义、
215 一页显示数据条数,显示快速跳转
216 */}
217 <Table
218 bordered
219 rowKey='_id'
220 dataSource={parentId==='0'? categorys:subCategorys}
221 columns={this.columns}
222 loading={loading}
223 pagination={{defaultPageSize: 5, showQuickJumper: true}}
224 />
225
226
227 {/*添加对话框:0:都不显示,1:显示添加分类,2:显示更新分类
228 添加监听函数:addCate,updateCate,handleCancel
229 使用<AddCateForm组件
230
231 */}
232 <Modal
233 title="添加分类"
234 visible={showStatus===1}
235 onOk={this.addCate}
236 onCancel={this.handleCancel}
237 >
238 {/**【1】把categorys,和parentId、接收子组件from对象的函数、传到子组件add-cate-form.jsx里面 */}
239 <AddCateForm
240 categorys={categorys}
241 parentId={parentId}
242 setForm={(form)=>{this.form=form}}
243 />
244 </Modal>
245
246 {/*
247 在updateCateForm组件加一个参数categoryName用于传给子组件,
248 实现更新时显示当前条目的产品分类名称
249 转到update-cate-form.jsx内接收传过来的参数categoryName
250 onOk点执行updateCate函数执行分类名修改
251 */}
252 <Modal
253 title="修改分类"
254 visible={showStatus===2}
255 onOk={this.updateCate}
256 onCancel={this.handleCancel}
257 >
258 {/*接收子组件传来的form对象(向子组件传递带参数的函数,子组件调用它,再把from对象通过参数传回来)
259 子组件把form对象传来之前,将其赋值到this.from里
260 下接update-cate-form.jsx*/}
261 <UpdateCateForm
262 categoryName={categoryOjb.name}
263 setForm={(form)=>{this.form=form}}
264 />
265 </Modal>
266
267 </Card>
268 </div>
269 )
270 }
271}
272
273 |
点【添加分类】成功添加分类,关闭对话框、显示添加成功、重新加载显示分类

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 284 285 286
| 1import React,{Component} from 'react'
2import './index.less'
3import {
4 Button,
5 Card,
6 Table,
7 Icon,
8 Modal, //引入对话框
9 message,} from 'antd';
10import LinkButton from '../../../components/link-button'
11import {reqCategorys,reqAddCategory,reqUpdateCategory} from '../../../api/' //获取api接口请求函数
12import AddCateForm from './add-cate-form'; //添加分类表单
13import UpdateCateForm from './update-cate-form'; //导入更新分类的表单
14
15export default class Category extends Component{
16 state={
17 loading:false, //控制是否显示加载动画
18 parentId:'0', //初始为0即请求一级产品分类列表
19 categorys:[], //存放api接口获取的分类列表
20 parentName:'', //当前子分类的对应父分类名
21 subCategorys:[], //子分类列表数据
22 showStatus:0, //添加分类、更新分类显示状态,0:都不显示,1:显示添加,2:显示更新
23 }
24
25
26 //异步请求一级分类列表
27 getCategorys = async (parentId)=>{
28 this.setState({loading:true}) //设置加载中动画状态显示
29 parentId=parentId || this.state.parentId //parentId等于传进来的参数或state里的值
30 const result=await reqCategorys(parentId) //把0改为从state内动态获取,请求分类数据并赋值给result
31 if(result.status===0){ //如果返回的status=0,说明返回成功,执行:
32 console.log(result.data) //测试输出返回的数据
33 const categorys=result.data //把返回数据赋值给categorys
34
35 //如果parentId=0则是一级列表,执行:
36 if(parentId==='0'){
37 this.setState({
38 categorys, //(因为名称和state标签名相同,所以用简写)把返回的一级产品分类数据,赋值给state里
39 loading:false, //数据加载完成,取消loading动画显示
40 })
41 }else{//否则是二级列表,执行:
42 this.setState({
43 subCategorys:categorys, //把返回的二级产品分类数据,赋值给state里
44 loading:false, //数据加载完成,取消loading动画显示
45 })
46 }
47
48 }else{
49 message.error('获取分类列表失败')
50 }
51 }
52
53 //显示一级分类对应二级产品分类函数
54 showSubCategory=(category)=>{
55 //先更新状state的parentId为对应新分类的id
56 this.setState({
57 parentId:category._id,
58 parentName:category.name
59 },()=>{/*setState是异步执行,并不会马上更新完状态,
60 因此需在其内部写(在状态更新且重新render()后执行)*/
61 console.log('parentId',this.state.parentId)
62 this.getCategorys()//获取二级分类列表
63 })
64
65 }
66
67 //显示一级分类函数,设置id状态即可
68 showCategorys=()=>{
69 this.setState({
70 parentId:'0',
71 parentName:'',
72 subCategorys:[],
73 })
74 }
75
76 //初始化表格column列名函数
77 initColumn=()=>{
78 //表格列名
79 this.columns = [
80 {
81 title: '分类名',
82 key: 'name',
83 dataIndex: 'name',
84 },
85 {
86 title: '操作',
87 width:'29%',
88 render: (categoryObj) => (//category代表当前条目对象(名字随意),用于返回需要显示的界面标签
89 <span>
90 {/*把当前条目的数据对象传递给updateCate函数 */}
91 <LinkButton onClick={()=>this.showUpdateCate(categoryObj)}>修改分类</LinkButton>
92 {/*
93 添加事件监听点击时调用显示函数
94 因为如果加括号及参数就会自动执行函数,而不是点击后才执行,所以用一个匿名函数把它包起来
95 如果parentId=0即是父级列表则显示查看子分类按钮,否则什么也不显示
96 */}
97 {this.state.parentId==='0'?<LinkButton onClick={()=>{this.showSubCategory(categoryObj)}}>查看子分类</LinkButton>:null}
98 </span>
99 ),
100 },
101
102 ];
103 }
104
105
106 //显示添加分类函数
107 showAddCate= async (parentId,categoryName)=>{
108 this.setState({
109 showStatus:1
110 })
111 }
112
113 //更新分类函数updateCate,接收[2]传来的对应条目数据对象
114 showUpdateCate=(categoryObj)=>{
115 //接收参数赋值到当前函数
116 this.categoryObj=categoryObj
117 this.setState({
118 showStatus:2
119 })
120 }
121
122 //取消对话框函数handleCancel
123 handleCancel=()=>{
124 //重置所有表单数据,防止上一条数据修改后点取消,下一条使用缓存,点其它条目时展示上一条修改的数据
125 this.form.resetFields()
126 this.setState({
127 showStatus:0
128 })
129 }
130
131
132 //执行添加分类:
133 addCate= async ()=>{
134 //1.获取表单数据
135 const {parentId,categoryName}=this.form.getFieldsValue()
136 //2.清除表单数据
137 this.form.resetFields()
138 const result = await reqAddCategory(parentId,categoryName)
139 if(result.status===0){//3.如果添加成功:
140 // 【1】如果新添加的分类就是当前分类下的子分类(当前表单显示的parentId=状态中的parentId):
141 if(parentId===this.state.parentId){
142 //隐藏对话框,提示添加成功
143 this.setState({showStatus:0})
144 message.success('产品分类添加成功')
145 //重新加载请求并展示添加之后的产品分类
146 this.getCategorys()
147 }else if(parentId==='0'){//【2】如果添加的是一级分类(parentId===0),则需获取一级分类,但无需显示
148 //【3】正常要重新设置state里的parentId=0然后再请求一次,但这样会造成跳转到一级分类
149 //因此把parentId直接做为参数传到getCategorys()里,这样就不会跳转显示一级分类,还是在二级分类里了
150 this.getCategorys('0')
151 //隐藏对话框,提示添加成功
152 this.setState({showStatus:0})
153 message.success('产品分类添加成功')
154 }else{//否则(添加其它分类下的子分类)
155 message.error('不能添加其它分类的子分类!')
156 }
157
158 }else{//6.添加失败:
159 message.error('产品分类添加失败')
160 }
161 }
162
163
164 //执行修改分类(点对话框的ok按钮执行此函数)
165 updateCate= async ()=>{
166 //1.点ok后隐藏对话框
167 this.setState({showStatus:0})
168 //2.准备数据
169 const categoryId=this.categoryObj._id
170 //从子组件update-cate-form.jsx组件获取要修改的分类名
171 const categoryName=this.form.getFieldValue('categoryName') //取this的form对象
172 // console.log('categoryId:',categoryId)
173 // console.log('categoryName:',categoryName)
174 //重置所有表单数据,防止使用缓存,造成点其它条目时展示上一条修改的数据
175 this.form.resetFields()
176 //3.发送请求更新分类
177 const result = await reqUpdateCategory({categoryId,categoryName})
178
179 if(result.status===0){
180 message.success('产品分类修改名称成功')
181 //4.重新显示修改名称后的分类列表
182 this.getCategorys()
183 }else{
184 message.error('产品分类修改名称失败')
185 }
186 }
187
188 // 页面完成加载后运行,用于异步加载等函数存放
189 componentDidMount(){
190 this.getCategorys() //获取表格数据源
191 }
192
193 // 页面将要加载运行:用于页面渲染前的数据准备
194 componentWillMount(){
195 this.initColumn() //准备表格列名相关数据
196 //this.addCate('5e41578325a557082c18f43b','洗衣机')
197 }
198
199 render(){
200 // 对state里数据解构:
201 const {categorys,subCategorys, parentId,parentName,loading,showStatus}=this.state
202 //把4步收到的参数赋值给categoryObj
203 const categoryOjb = this.categoryObj || {} // 如果还没有,则指定一个空对象
204
205 //卡片标题,如果是一及分类显示 一级分类列表,否则显示一级分类+链接+对应的一级分类名
206 const title= parentId==='0'?'一级分类列表':(
207 <span>
208 <LinkButton onClick={this.showCategorys}>一级分类列表</LinkButton> >>
209 <span>{parentName}</span>
210 </span>
211 )
212 //卡片右侧添加按键:添加监听
213 const extra=(
214 <Button type='primary' onClick={this.showAddCate}>
215 <Icon type='plus'/>
216 添加
217 </Button>
218 )
219
220 return(
221 <div className='category'>
222 {/*卡片样式组件*/}
223 <Card title={title} extra={extra} >
224 {/*
225 表格组件、边框、key为数据源的_id、
226 数据源、如果parentId为0设置一级分类列表为数据源、否则二级分类为列表源
227 列名定义、
228 一页显示数据条数,显示快速跳转
229 */}
230 <Table
231 bordered
232 rowKey='_id'
233 dataSource={parentId==='0'? categorys:subCategorys}
234 columns={this.columns}
235 loading={loading}
236 pagination={{defaultPageSize: 5, showQuickJumper: true}}
237 />
238
239
240 {/*添加对话框:0:都不显示,1:显示添加分类,2:显示更新分类
241 添加监听函数:addCate,updateCate,handleCancel
242 使用<AddCateForm组件
243
244 */}
245 <Modal
246 title="添加分类"
247 visible={showStatus===1}
248 onOk={this.addCate}
249 onCancel={this.handleCancel}
250 >
251 {/**把categorys,和parentId、接收子组件from对象的函数、传到子组件add-cate-form.jsx里面 */}
252 <AddCateForm
253 categorys={categorys}
254 parentId={parentId}
255 setForm={(form)=>{this.form=form}}
256 />
257 </Modal>
258
259 {/*
260 在updateCateForm组件加一个参数categoryName用于传给子组件,
261 实现更新时显示当前条目的产品分类名称
262 转到update-cate-form.jsx内接收传过来的参数categoryName
263 onOk点执行updateCate函数执行分类名修改
264 */}
265 <Modal
266 title="修改分类"
267 visible={showStatus===2}
268 onOk={this.updateCate}
269 onCancel={this.handleCancel}
270 >
271 {/*接收子组件传来的form对象(向子组件传递带参数的函数,子组件调用它,再把from对象通过参数传回来)
272 子组件把form对象传来之前,将其赋值到this.from里
273 下接update-cate-form.jsx*/}
274 <UpdateCateForm
275 categoryName={categoryOjb.name}
276 setForm={(form)=>{this.form=form}}
277 />
278 </Modal>
279
280 </Card>
281 </div>
282 )
283 }
284}
285
286 |
6.4添加表单验证:更新表单验证
antd表单及规则编写
【1】在字段装饰器加入规则【2】到父组件内写验证
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| 1<Item>
2 <span>添加子分类:</span>
3 {
4 getFieldDecorator('categoryName',{
5 //【1】在字段装饰器加入规则【2】到父组件内写验证
6 rules:[
7 {required:true,message:'分类名称必须输入'}
8 ]
9 })(
10
11 <Input type='text' placeholder='请输入子分类名称' />
12 )
13 }
14</Item>
15
16 |
表单验证函数
1 2 3 4 5 6 7 8 9
| 1//antd的表单验证函数结构
2this.form.validateFields((err,values)=>{
3//如果没有错误
4 if(!err){
5 //写点ok提交数据要执行的代码
6 }
7})
8
9 |
表单验证完整函数
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
| 1//执行添加分类:
2 addCate= ()=>{
3 //【1】antd表单验证函数
4 this.form.validateFields(async (err,values)=>{
5 if(!err){//【2】把所有提交数据要执行的代码都放入表单验证无错误之后
6 //1.获取表单数据
7 // const {parentId,categoryName}=this.form.getFieldsValue()
8 //【3】注释旧上一行,改成从values里解构需要的数据
9 const {parentId,categoryName}=values
10 //2.清除表单数据
11 this.form.resetFields()
12 const result = await reqAddCategory(parentId,categoryName)
13 if(result.status===0){//3.如果添加成功:
14 // 如果新添加的分类就是当前分类下的子分类(当前表单显示的parentId=状态中的parentId):
15 if(parentId===this.state.parentId){
16 //隐藏对话框,提示添加成功
17 this.setState({showStatus:0})
18 message.success('产品分类添加成功')
19 //重新加载请求并展示添加之后的产品分类
20 this.getCategorys()
21 }else if(parentId==='0'){//如果添加的是一级分类(parentId===0),则需获取一级分类,但无需显示
22 //正常要重新设置state里的parentId=0然后再请求一次,但这样会造成跳转到一级分类
23 //因此把parentId直接做为参数传到getCategorys()里,这样就不会跳转显示一级分类,还是在二级分类里了
24 this.getCategorys('0')
25 //隐藏对话框,提示添加成功
26 this.setState({showStatus:0})
27 message.success('产品分类添加成功')
28 }else{
29 message.error('不能添加其它分类的子分类!')
30 }
31
32 }else{//6.添加失败:
33 message.error('产品分类添加失败')
34 }
35 }
36 })
37 }
38
39 |
6.5更新产品分类的表单验证
表单部分update-cate-form.jsx
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| 1<Item>
2 {/**因为getFiledDecorator接收的标签必须为Form标签,因此span必须拿出来 */}
3 <span>修改分类名:</span>
4 {
5 getFieldDecorator('categoryName',{
6 //文本框默认值为父组件传过来的对应条目数据的名字
7 initialValue:categoryName,
8 //【1】加入规则【2】到父组件内写验证
9 rules:[
10 {required:true,message:'分类名称必须输入'}
11 ]
12 })(
13
14 <Input type='text' placeholder='请输入子分类名称' />
15 )
16 }
17
18 </Item>
19
20 |
验证部分category/index.jsx:
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
| 1//执行修改分类(点对话框的ok按钮执行此函数)
2 updateCate= ()=>{
3 //【1】表单的验证函数
4 this.form.validateFields(async(err,values)=>{
5 //【2】如果没错
6 if(!err){
7 //1.点ok后隐藏对话框
8 this.setState({showStatus:0})
9 //2.准备数据
10 const categoryId=this.categoryObj._id
11 //从子组件update-cate-form.jsx组件获取要修改的分类名
12 //const categoryName=this.form.getFieldValue('categoryName') //取this的form对象
13 //【3】注释上一行,改成如下从values解构
14 const {categoryName}=values
15 // console.log('categoryId:',categoryId)
16 // console.log('categoryName:',categoryName)
17 //重置所有表单数据,防止使用缓存,造成点其它条目时展示上一条修改的数据
18 this.form.resetFields()
19 //3.发送请求更新分类
20 const result = await reqUpdateCategory({categoryId,categoryName})
21
22 if(result.status===0){
23 message.success('产品分类修改名称成功')
24 //4.重新显示修改名称后的分类列表
25 this.getCategorys()
26 }else{
27 message.error('产品分类修改名称失败')
28 }
29 }
30 })
31
32
33 }
34
35 |
6.4-6.5完整代码
index.jsx
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 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304
| 1import React,{Component} from 'react'
2import './index.less'
3import {
4 Button,
5 Card,
6 Table,
7 Icon,
8 Modal, //引入对话框
9 message,} from 'antd';
10import LinkButton from '../../../components/link-button'
11import {reqCategorys,reqAddCategory,reqUpdateCategory} from '../../../api/' //获取api接口请求函数
12import AddCateForm from './add-cate-form'; //添加分类表单
13import UpdateCateForm from './update-cate-form'; //导入更新分类的表单
14
15export default class Category extends Component{
16 state={
17 loading:false, //控制是否显示加载动画
18 parentId:'0', //初始为0即请求一级产品分类列表
19 categorys:[], //存放api接口获取的分类列表
20 parentName:'', //当前子分类的对应父分类名
21 subCategorys:[], //子分类列表数据
22 showStatus:0, //添加分类、更新分类显示状态,0:都不显示,1:显示添加,2:显示更新
23 }
24
25
26 //异步请求一级分类列表
27 getCategorys = async (parentId)=>{
28 this.setState({loading:true}) //设置加载中动画状态显示
29 parentId=parentId || this.state.parentId //parentId等于传进来的参数或state里的值
30 const result=await reqCategorys(parentId) //把0改为从state内动态获取,请求分类数据并赋值给result
31 if(result.status===0){ //如果返回的status=0,说明返回成功,执行:
32 console.log(result.data) //测试输出返回的数据
33 const categorys=result.data //把返回数据赋值给categorys
34
35 //如果parentId=0则是一级列表,执行:
36 if(parentId==='0'){
37 this.setState({
38 categorys, //(因为名称和state标签名相同,所以用简写)把返回的一级产品分类数据,赋值给state里
39 loading:false, //数据加载完成,取消loading动画显示
40 })
41 }else{//否则是二级列表,执行:
42 this.setState({
43 subCategorys:categorys, //把返回的二级产品分类数据,赋值给state里
44 loading:false, //数据加载完成,取消loading动画显示
45 })
46 }
47
48 }else{
49 message.error('获取分类列表失败')
50 }
51 }
52
53 //显示一级分类对应二级产品分类函数
54 showSubCategory=(category)=>{
55 //先更新状state的parentId为对应新分类的id
56 this.setState({
57 parentId:category._id,
58 parentName:category.name
59 },()=>{/*setState是异步执行,并不会马上更新完状态,
60 因此需在其内部写(在状态更新且重新render()后执行)*/
61 console.log('parentId',this.state.parentId)
62 this.getCategorys()//获取二级分类列表
63 })
64
65 }
66
67 //显示一级分类函数,设置id状态即可
68 showCategorys=()=>{
69 this.setState({
70 parentId:'0',
71 parentName:'',
72 subCategorys:[],
73 })
74 }
75
76 //初始化表格column列名函数
77 initColumn=()=>{
78 //表格列名
79 this.columns = [
80 {
81 title: '分类名',
82 key: 'name',
83 dataIndex: 'name',
84 },
85 {
86 title: '操作',
87 width:'29%',
88 render: (categoryObj) => (//category代表当前条目对象(名字随意),用于返回需要显示的界面标签
89 <span>
90 {/*把当前条目的数据对象传递给updateCate函数 */}
91 <LinkButton onClick={()=>this.showUpdateCate(categoryObj)}>修改分类</LinkButton>
92 {/*
93 添加事件监听点击时调用显示函数
94 因为如果加括号及参数就会自动执行函数,而不是点击后才执行,所以用一个匿名函数把它包起来
95 如果parentId=0即是父级列表则显示查看子分类按钮,否则什么也不显示
96 */}
97 {this.state.parentId==='0'?<LinkButton onClick={()=>{this.showSubCategory(categoryObj)}}>查看子分类</LinkButton>:null}
98 </span>
99 ),
100 },
101
102 ];
103 }
104
105
106 //显示添加分类函数
107 showAddCate= async (parentId,categoryName)=>{
108 this.setState({
109 showStatus:1
110 })
111 }
112
113 //更新分类函数updateCate,接收[2]传来的对应条目数据对象
114 showUpdateCate=(categoryObj)=>{
115 //接收参数赋值到当前函数
116 this.categoryObj=categoryObj
117 this.setState({
118 showStatus:2
119 })
120 }
121
122 //取消对话框函数handleCancel
123 handleCancel=()=>{
124 //重置所有表单数据,防止上一条数据修改后点取消,下一条使用缓存,点其它条目时展示上一条修改的数据
125 this.form.resetFields()
126 this.setState({
127 showStatus:0
128 })
129 }
130
131
132 //执行添加分类:
133 addCate= ()=>{
134 //【1】antd表单验证函数
135 this.form.validateFields(async (err,values)=>{
136 if(!err){//【2】把所有提交数据要执行的代码都放入表单验证无错误之后
137 //1.获取表单数据
138 // const {parentId,categoryName}=this.form.getFieldsValue()
139 //【3】注释旧上一行,改成从values里解构需要的数据
140 const {parentId,categoryName}=values
141 //2.清除表单数据
142 this.form.resetFields()
143 const result = await reqAddCategory(parentId,categoryName)
144 if(result.status===0){//3.如果添加成功:
145 // 如果新添加的分类就是当前分类下的子分类(当前表单显示的parentId=状态中的parentId):
146 if(parentId===this.state.parentId){
147 //隐藏对话框,提示添加成功
148 this.setState({showStatus:0})
149 message.success('产品分类添加成功')
150 //重新加载请求并展示添加之后的产品分类
151 this.getCategorys()
152 }else if(parentId==='0'){//如果添加的是一级分类(parentId===0),则需获取一级分类,但无需显示
153 //正常要重新设置state里的parentId=0然后再请求一次,但这样会造成跳转到一级分类
154 //因此把parentId直接做为参数传到getCategorys()里,这样就不会跳转显示一级分类,还是在二级分类里了
155 this.getCategorys('0')
156 //隐藏对话框,提示添加成功
157 this.setState({showStatus:0})
158 message.success('产品分类添加成功')
159 }else{
160 message.error('不能添加其它分类的子分类!')
161 }
162
163 }else{//6.添加失败:
164 message.error('产品分类添加失败')
165 }
166 }
167 })
168
169 }
170
171
172 //执行修改分类(点对话框的ok按钮执行此函数)
173 updateCate= ()=>{
174 //【1】表单的验证函数
175 this.form.validateFields(async(err,values)=>{
176 //【2】如果没错
177 if(!err){
178 //1.点ok后隐藏对话框
179 this.setState({showStatus:0})
180 //2.准备数据
181 const categoryId=this.categoryObj._id
182 //从子组件update-cate-form.jsx组件获取要修改的分类名
183 //const categoryName=this.form.getFieldValue('categoryName') //取this的form对象
184 //【3】注释上一行,改成如下从values解构
185 const {categoryName}=values
186 // console.log('categoryId:',categoryId)
187 // console.log('categoryName:',categoryName)
188 //重置所有表单数据,防止使用缓存,造成点其它条目时展示上一条修改的数据
189 this.form.resetFields()
190 //3.发送请求更新分类
191 const result = await reqUpdateCategory({categoryId,categoryName})
192
193 if(result.status===0){
194 message.success('产品分类修改名称成功')
195 //4.重新显示修改名称后的分类列表
196 this.getCategorys()
197 }else{
198 message.error('产品分类修改名称失败')
199 }
200 }
201 })
202
203
204 }
205
206 // 页面完成加载后运行,用于异步加载等函数存放
207 componentDidMount(){
208 this.getCategorys() //获取表格数据源
209 }
210
211 // 页面将要加载运行:用于页面渲染前的数据准备
212 componentWillMount(){
213 this.initColumn() //准备表格列名相关数据
214 //this.addCate('5e41578325a557082c18f43b','洗衣机')
215 }
216
217 render(){
218 // 对state里数据解构:
219 const {categorys,subCategorys, parentId,parentName,loading,showStatus}=this.state
220 //把4步收到的参数赋值给categoryObj
221 const categoryOjb = this.categoryObj || {} // 如果还没有,则指定一个空对象
222
223 //卡片标题,如果是一及分类显示 一级分类列表,否则显示一级分类+链接+对应的一级分类名
224 const title= parentId==='0'?'一级分类列表':(
225 <span>
226 <LinkButton onClick={this.showCategorys}>一级分类列表</LinkButton> >>
227 <span>{parentName}</span>
228 </span>
229 )
230 //卡片右侧添加按键:添加监听
231 const extra=(
232 <Button type='primary' onClick={this.showAddCate}>
233 <Icon type='plus'/>
234 添加
235 </Button>
236 )
237
238 return(
239 <div className='category'>
240 {/*卡片样式组件*/}
241 <Card title={title} extra={extra} >
242 {/*
243 表格组件、边框、key为数据源的_id、
244 数据源、如果parentId为0设置一级分类列表为数据源、否则二级分类为列表源
245 列名定义、
246 一页显示数据条数,显示快速跳转
247 */}
248 <Table
249 bordered
250 rowKey='_id'
251 dataSource={parentId==='0'? categorys:subCategorys}
252 columns={this.columns}
253 loading={loading}
254 pagination={{defaultPageSize: 5, showQuickJumper: true}}
255 />
256
257
258 {/*添加对话框:0:都不显示,1:显示添加分类,2:显示更新分类
259 添加监听函数:addCate,updateCate,handleCancel
260 使用<AddCateForm组件
261
262 */}
263 <Modal
264 title="添加分类"
265 visible={showStatus===1}
266 onOk={this.addCate}
267 onCancel={this.handleCancel}
268 >
269 {/**把categorys,和parentId、接收子组件from对象的函数、传到子组件add-cate-form.jsx里面 */}
270 <AddCateForm
271 categorys={categorys}
272 parentId={parentId}
273 setForm={(form)=>{this.form=form}}
274 />
275 </Modal>
276
277 {/*
278 在updateCateForm组件加一个参数categoryName用于传给子组件,
279 实现更新时显示当前条目的产品分类名称
280 转到update-cate-form.jsx内接收传过来的参数categoryName
281 onOk点执行updateCate函数执行分类名修改
282 */}
283 <Modal
284 title="修改分类"
285 visible={showStatus===2}
286 onOk={this.updateCate}
287 onCancel={this.handleCancel}
288 >
289 {/*接收子组件传来的form对象(向子组件传递带参数的函数,子组件调用它,再把from对象通过参数传回来)
290 子组件把form对象传来之前,将其赋值到this.from里
291 下接update-cate-form.jsx*/}
292 <UpdateCateForm
293 categoryName={categoryOjb.name}
294 setForm={(form)=>{this.form=form}}
295 />
296 </Modal>
297
298 </Card>
299 </div>
300 )
301 }
302}
303
304 |
update-cate-fomr.jsx
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
| 1import React,{Component} from 'react'
2import {
3 Form,
4 Select,
5 Input
6} from 'antd'
7import PropTypes from 'prop-types' //接收父组件传值组件
8
9const Item=Form.Item
10const Option=Select.Option
11
12class UpdateCateForm extends Component{
13 //把从父组件接收过来的属性参数接收过来
14 static propTypes={
15 categoryName:PropTypes.string.isRequired,
16 //设置setForm类型为函数且必须
17 setForm:PropTypes.func.isRequired,
18 }
19
20 //在此组件渲染之前调用一次setForm函数,把form传到父组件去
21 componentWillMount(){
22 //将form对象通过setForm函数传给父组件
23 this.props.setForm(this.props.form)
24 }
25
26 render(){
27 //把categoryName解构出来
28 const {categoryName} = this.props
29 const { getFieldDecorator } = this.props.form
30 return(
31 <Form>
32 {/*<Item>
33 <span>所属分类:</span>
34 {
35 getFieldDecorator('parentId',{
36 initialValue:parentId
37 })(
38 <Select>
39 <Option value='1'>一级分类</Option>
40 </Select>
41 )
42 }
43
44 </Item>*/}
45
46 <Item>
47 {/**因为getFiledDecorator接收的标签必须为Form标签,因此span必须拿出来 */}
48 <span>修改分类名:</span>
49 {
50 getFieldDecorator('categoryName',{
51 //文本框默认值为父组件传过来的对应条目数据的名字
52 initialValue:categoryName,
53 //【1】加入规则【2】到父组件内写验证
54 rules:[
55 {required:true,message:'分类名称必须输入'}
56 ]
57 })(
58
59 <Input type='text' placeholder='请输入子分类名称' />
60 )
61 }
62
63 </Item>
64
65 </Form>
66 )
67 }
68}
69export default Form.create()(UpdateCateForm);
70
71 |
add-cate-form.jsx
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
| 1import React,{Component} from 'react'
2import {
3 Form,
4 Select,
5 Input
6} from 'antd'
7import PropTypes from 'prop-types' //接收父组件传值组件
8
9const Item=Form.Item
10const Option=Select.Option
11
12class UpdateCateForm extends Component{
13 //把从父组件接收过来的属性参数接收过来
14 static propTypes={
15 categoryName:PropTypes.string.isRequired,
16 //设置setForm类型为函数且必须
17 setForm:PropTypes.func.isRequired,
18 }
19
20 //在此组件渲染之前调用一次setForm函数,把form传到父组件去
21 componentWillMount(){
22 //将form对象通过setForm函数传给父组件
23 this.props.setForm(this.props.form)
24 }
25
26 render(){
27 //把categoryName解构出来
28 const {categoryName} = this.props
29 const { getFieldDecorator } = this.props.form
30 return(
31 <Form>
32 {/*<Item>
33 <span>所属分类:</span>
34 {
35 getFieldDecorator('parentId',{
36 initialValue:parentId
37 })(
38 <Select>
39 <Option value='1'>一级分类</Option>
40 </Select>
41 )
42 }
43
44 </Item>*/}
45
46 <Item>
47 {/**因为getFiledDecorator接收的标签必须为Form标签,因此span必须拿出来 */}
48 <span>修改分类名:</span>
49 {
50 getFieldDecorator('categoryName',{
51 //文本框默认值为父组件传过来的对应条目数据的名字
52 initialValue:categoryName,
53 //【1】加入规则【2】到父组件内写验证
54 rules:[
55 {required:true,message:'分类名称必须输入'}
56 ]
57 })(
58
59 <Input type='text' placeholder='请输入子分类名称' />
60 )
61 }
62
63 </Item>
64
65 </Form>
66 )
67 }
68}
69export default Form.create()(UpdateCateForm);
70
71 |

