官方文档
https://www.yuque.com/ant-design/course
https://ant.design/docs/react/introduce-cn
https://pro.ant.design/docs/getting-started-cn
https://umijs.org/zh/guide/
增删改查Demo
1.项目结构
我使用的是Ant Design Pro,自己添加了一个模块,目录结构如下,路由相关配置请查看官方文档





2.index.jsx
import React, { Component } from 'react';
import { Button, Form, Table, Popconfirm, Row, Col, message, } from 'antd';
import { connect } from 'dva';
import CreateForm from './components/CreateForm';
import UpdateForm from './components/UpdateForm';
const mapStateToProps = ({ member, loading }) => {
return {
cardList: member.cardList,
cardsLoading: loading.effects['member/queryInitCards'],
};
};
@connect(mapStateToProps)
class Member extends Component {
state = {
modalVisible: false,
updateModalVisible: false,
stepFormValues: {},
}
//初始化列表
componentDidMount() {
this.props.dispatch({
type: "member/queryInitCards"
});
}
//显示/隐藏添加弹框
handleModalVisible = flag => {
this.setState({
modalVisible: !!flag,
});
};
//提交添加
handleAdd = fields => {
const { dispatch } = this.props;
dispatch({
type: "member/addCard",
payload: fields,
});
message.success('添加成功');
this.handleModalVisible();
}
//显示/隐藏编辑弹框
handleUpdateModalVisible = (flag, record) => {
this.setState({
updateModalVisible: !!flag,
stepFormValues: record || {},
});
};
//提交编辑
handleUpdate = fields => {
const { dispatch } = this.props;
dispatch({
type: "member/updateCard",
payload: fields,
});
message.success('编辑成功');
this.handleUpdateModalVisible();
}
//删除
onDeleteCard(card) {
this.props.dispatch({
type: "member/deleteCard",
payload: card,
});
}
render() {
const { modalVisible, updateModalVisible, stepFormValues } = this.state;
const columns = [
{ title: '编号', dataIndex: 'id' },
{ title: '姓名', dataIndex: 'name' },
{ title: '性别', dataIndex: 'sex' },
{ title: '手机', dataIndex: 'phone' },
{
title: '操作',
dataIndex: 'caozuo',
render: (text, record) => (
<div>
<a onClick={() => this.handleUpdateModalVisible(true, record)}>编辑</a>
<Popconfirm
title="确定要删除吗?"
okText="继续"
cancelText="取消"
onConfirm={() => this.onDeleteCard(record)}
>
<a style={{ marginLeft: 10 }}>删除</a>
</Popconfirm>
</div>
),
},
];
const expandedRow = (record) => {
return (
<div>
<Row>
<Col span={3} offset={8}>属性名</Col>
<Col span={3}>属性值</Col>
</Row>
{record.attrs.map((item, index) => (
<Row>
<Col span={3} offset={8}>{item.key}</Col>
<Col span={3}>{item.value}</Col>
</Row>
))}
</div>
)
}
const UpdateModalMethods = {
handleUpdateModalVisible: this.handleUpdateModalVisible,
handleUpdate: this.handleUpdate
};
const parentMethods = {
handleModalVisible: this.handleModalVisible,
handleAdd: this.handleAdd
};
return (
<div>
<div style={{marginBottom:20}}>
<Button onClick={() => this.handleModalVisible(true)}> 添加 </Button>
</div>
<Table
columns={columns}
expandedRowRender={record => expandedRow(record)}
dataSource={this.props.cardList}
loading={this.props.cardsLoading}
>
</Table>
<CreateForm {...parentMethods} modalVisible={modalVisible} ></CreateForm>
{stepFormValues && Object.keys(stepFormValues).length ? (
<UpdateForm {...UpdateModalMethods} updateModalVisible={updateModalVisible} values={stepFormValues} />
) : null}
</div>
);
}
}
export default Form.create()(Member);
3.model.js
import { queryCard } from './service';
const delay = (millisecond) => {
return new Promise((resolve) => {
setTimeout(resolve, millisecond);
});
};
// yield call(delay, 3000);
export default {
namespace: 'member',
state: {
cardList: []
},
effects: {
*queryInitCards(_, sagaEffects) {
const { call, put } = sagaEffects;
const cards = yield call(queryCard);
yield put({ type: 'loadCards', payload: cards });
}
},
reducers: {
loadCards(state, { payload: cards }) {
return {
cardList: cards
}
},
addCard(state, { payload: card }) {
card.id = new Date().getTime()
let cards = state.cardList.concat(card)
return {
cardList: cards
}
},
updateCard(state, { payload: card }) {
let cards = state.cardList
cards.map((item, index) => {
if (item.id == card.id) {
cards[index] = card
}
})
return {
cardList: cards
}
},
deleteCard(state, { payload: card }) {
let id = card.id
let cards = state.cardList
for (let i = 0; i < cards.length; i++) {
if (cards[i].id == id) {
cards.splice(i, 1)
break;
}
}
return {
// cardList: cards,//不知道为什么返回这个对象,列表中不删除
cardList: JSON.parse(JSON.stringify(cards))
}
}
},
};
4.service.js
import request from '@/utils/request';
export async function queryCard() {
return request('/dev/random_joke');
}
5._mock.js
function randomJokes(req, res) {
const responseObj = [
{
id: 1,
name:"郭南林",
sex:"男",
phone:"18000000000",
attrs:[
{
key:"身高",
value:"185cm"
},
{
key:"体重",
value:"75kg"
}
]
},
{
id: 2,
name:"张三",
sex:"男",
phone:"18000000001",
attrs:[
{
key:"身高",
value:"180cm"
},
{
key:"体重",
value:"70kg"
}
]
},
{
id: 3,
name:"李四",
sex:"女",
phone:"18000000002",
attrs:[
{
key:"身高",
value:"165cm"
},
{
key:"体重",
value:"50kg"
}
]
},
]
setTimeout(() => {
return res.json(responseObj);
}, 0);
}
export default {
'get /dev/random_joke': randomJokes
};
6.CreateForm.jsx
import { Form, Input, Modal, Row, Col, Button } from 'antd';
import React, { Component } from 'react';
const FormItem = Form.Item;
class CreateForm extends Component {
state = {
attrs: [{}]
}
//添加项
addItem = e => {
let attrs = this.state.attrs
attrs = attrs.concat({})
this.setState({
attrs: attrs
})
};
//删除项
subItem = (index) => {
let attrs = this.state.attrs
attrs.splice(index, 1)
this.setState({
attrs: attrs
})
};
render() {
const { modalVisible, form, handleAdd, handleModalVisible } = this.props;
const { getFieldDecorator } = form;
const okHandle = () => {
form.validateFields((err, fieldsValue) => {
if (err) return;
form.resetFields();
console.log(fieldsValue)
handleAdd(fieldsValue);
});
};
const formItem = {
labelCol: {
span: 5,
},
wrapperCol: {
span: 15,
}
}
return (
<Modal
visible={modalVisible}
onOk={okHandle}
onCancel={() => handleModalVisible()}
title="新建"
>
<Form>
<FormItem label="id" hidden={true}>
{getFieldDecorator('id')(<Input />)}
</FormItem>
<FormItem label="姓名" {...formItem}>
{getFieldDecorator('name', {
rules: [
{
required: true,
message: "请输入",
},
],
})(<Input />)}
</FormItem>
<FormItem label="性别" {...formItem}>
{getFieldDecorator('sex', {
rules: [
{
required: true,
message: "请输入",
},
],
})(<Input />)}
</FormItem>
<FormItem label="手机" {...formItem}>
{getFieldDecorator('phone', {
rules: [
{
required: true,
message: "请输入",
},
],
})(<Input />)}
</FormItem>
<Row>
<Col span={6} offset={2}>
<div class="ant-form-item-required">属性名</div>
</Col>
<Col span={8} offset={1}>
<div>属性值</div>
</Col>
</Row>
{
this.state.attrs.map((item, index) => (
<Row>
<Col span={6} offset={2}>
<FormItem >
{getFieldDecorator('attrs[' + index + '].key', {
rules: [
{
required: true,
message: "请输入",
},
],
})(<Input />)}
</FormItem>
</Col>
<Col span={8} offset={1}>
<FormItem>
{getFieldDecorator('attrs[' + index + '].value', {
rules: [
{
required: true,
message: "请输入",
},
],
})(<Input />)}
</FormItem>
</Col>
<Col span={1} offset={1} style={{ marginTop: 8 }} hidden={this.state.attrs.length <= 1}>
<Button type="danger" shape="circle" icon="minus" size="small" onClick={() => this.subItem(index)} />
</Col>
<Col span={1} offset={1} style={{ marginTop: 8 }} hidden={this.state.attrs.length - 1 > index}>
<Button type="primary" shape="circle" icon="plus" size="small" onClick={this.addItem} />
</Col>
</Row>
))
}
</Form>
</Modal>
)
}
};
export default Form.create()(CreateForm);
7.UpdateForm.jsx
import { Form, Input, Modal, Row, Col, Button } from 'antd';
import React, { Component } from 'react';
const FormItem = Form.Item;
class UpdateForm extends Component {
static defaultProps = {
handleUpdate: () => { },
handleUpdateModalVisible: () => { },
values: {},
};
constructor(props) {
super(props);
this.state = {
formVals: {
...props.values
}
};
}
//添加项
addItem = e => {
let formVals = this.state.formVals
let attrs = formVals.attrs
formVals.attrs = attrs.concat({})
this.setState({
formVals: formVals
})
};
//删除项
subItem = (index) => {
let formVals = this.state.formVals
let attrs = formVals.attrs
attrs.splice(index, 1)
formVals.attrs = attrs
this.setState({
formVals: formVals
})
};
render() {
const { updateModalVisible, form, handleUpdate, handleUpdateModalVisible } = this.props;
const { formVals } = this.state;
const { getFieldDecorator } = form;
const okHandle = () => {
form.validateFields((err, fieldsValue) => {
if (err) return;
form.resetFields();
console.log(fieldsValue)
handleUpdate(fieldsValue);
});
};
const formItem = {
labelCol: {
span: 5,
},
wrapperCol: {
span: 15,
}
}
return (
<Modal
visible={updateModalVisible}
onOk={okHandle}
onCancel={() => handleUpdateModalVisible(false, null)}
title="编辑"
>
<Form>
<FormItem label="id" hidden={true}>
{getFieldDecorator('id', {
initialValue: formVals.id,
})(<Input />)}
</FormItem>
<FormItem label="姓名" {...formItem}>
{getFieldDecorator('name', {
initialValue: formVals.name,
rules: [
{
required: true,
message: "请输入",
},
],
})(<Input />)}
</FormItem>
<FormItem label="性别" {...formItem}>
{getFieldDecorator('sex', {
initialValue: formVals.sex,
rules: [
{
required: true,
message: "请输入",
},
],
})(<Input />)}
</FormItem>
<FormItem label="手机" {...formItem}>
{getFieldDecorator('phone', {
initialValue: formVals.phone,
rules: [
{
required: true,
message: "请输入",
},
],
})(<Input />)}
</FormItem>
<Row>
<Col span={6} offset={2}>
<div class="ant-form-item-required">属性名</div>
</Col>
<Col span={8} offset={1}>
<div>属性值</div>
</Col>
</Row>
{
formVals.attrs.map((item, index) => (
<Row>
<Col span={6} offset={2}>
<FormItem >
{getFieldDecorator('attrs[' + index + '].key', {
initialValue: item.key,
rules: [
{
required: true,
message: "请输入",
},
],
})(<Input />)}
</FormItem>
</Col>
<Col span={8} offset={1}>
<FormItem>
{getFieldDecorator('attrs[' + index + '].value', {
initialValue: item.value,
rules: [
{
required: true,
message: "请输入",
},
],
})(<Input />)}
</FormItem>
</Col>
<Col span={1} offset={1} style={{ marginTop: 8 }} hidden={formVals.attrs.length <= 1}>
<Button type="danger" shape="circle" icon="minus" size="small" onClick={() => this.subItem(index)} />
</Col>
<Col span={1} offset={1} style={{ marginTop: 8 }} hidden={formVals.attrs.length - 1 > index}>
<Button type="primary" shape="circle" icon="plus" size="small" onClick={this.addItem} />
</Col>
</Row>
))
}
</Form>
</Modal>
)
}
};
export default Form.create()(UpdateForm);
网友评论