1.首先在pages创建需要的界面
productList.jsx
import {Form, Input, Button, Table, Card, Divider, Modal, message, Select, Col} from 'antd';
import {PageHeaderWrapper} from '@ant-design/pro-layout';
import {connect} from 'dva';
import Add from './Add'
import Update from './Update'
import React, {useState, Component} from "react";
const Option = Select.Option
const dataSource = [
{
key: '1',
name: '胡彦斌',
age: 32,
address: '西湖区湖底公园1号',
},
{
key: '2',
name: '胡彦祖',
age: 42,
address: '西湖区湖底公园1号',
},
];
class ProductList extends Component {
columns = [
{
title: '产品id',
dataIndex: 'productId',
key: 'productId',
},
{
title: '产品编号',
dataIndex: 'productCode',
key: 'productCode',
},
{
title: '产品名称',
dataIndex: 'productName',
key: 'productName',
},
{
title: '产品类别',
dataIndex: 'categoryName',
key: 'categoryName',
},
{
title: '计量单位',
dataIndex: 'unit',
key: 'unit',
},
{
title: '单价',
dataIndex: 'unitPrice',
key: 'unitPrice',
},
{
title: '状态',
dataIndex: 'status',
key: 'status',
render: (text, record) => {
return (
{
1: <span style={{color: 'green'}}>有效</span>,
0: <span style={{color: 'red'}}>无效</span>
}[text]
)
}
},
{
title: '操作',
dataIndex: 'action',
key: 'action',
render: (text, record) => {
console.log(record, text)
return (
<span>
<Button type="primary" size='small' onClick={(e) => this.showUpdateModel(record)}>编辑</Button>
<Divider type="vertical"/>
<Button type="danger" size={"small"} onClick={(e) => this.handleClickDel(record.productId)}>删除</Button>
</span>
)
}
}
];
state = {
selectedRowKeys: [], // Check here to configure the default column
selectedProduct: [], // Check here to configure the default column
loading: false,
addModelShow: false,
updateModelShow: false,
//正在编辑的字段
oneProduct: {},
};
onSelectChange = selectedRowKeys => {
this.setState({selectedRowKeys});
};
componentDidMount() {
this.props.getProductList()
}
showAddModel = () => {
this.setState({addModelShow: true});
}
handleCancel = () => {
this.setState({addModelShow: false, updateModelShow: false});
}
/**
* 删除事件
* @param productId
*/
handleClickDel = (productId) => {
const del = this.props.delete
Modal.confirm({
title: '警告',
content: '你确认要删除id为' + productId + '的产品吗',
onOk() {
return new Promise((resolve, reject) => {
del(productId)
message.success('删除成功')
resolve()
}).catch(() => console.log('Oops errors!'));
},
});
}
/**
*
* @param product
*/
showUpdateModel = (oneProduct) => {
this.setState({updateModelShow: true, oneProduct});
}
//批量删除
handleClickBatchDel = () => {
const {selectedProduct} = this.state;
const _this = this;
const {batchDelete} = this.props;
if (selectedProduct && selectedProduct.length > 0) {
debugger
console.log(selectedProduct)
Modal.confirm({
title: '警告',
content: '你确认要删除选中的' + selectedProduct.length + '条产品吗',
onOk() {
//setState({selectedRowKeys:[],selectedProduct: []})
return new Promise((resolve, reject) => {
batchDelete(selectedProduct.map(e => e.productId))
message.success(`成功删除${selectedProduct.length}条记录`)
_this.setState({selectedRowKeys: [], selectedProduct: []})
resolve()
}).catch((res) => console.log(res));
},
});
} else {
message.error('请选择要删除的商品')
}
}
/**
* 输入框改变事件
* @param type
* @param val
*/
handleChangeInput = (type, val) => {
this.setState({
[type]: val,
})
}
render() {
const {selectedRowKeys, addModelShow, updateModelShow, oneProduct, selectedProduct} = this.state;
const {product, add, update, query} = this.props;
const {productList} = product;
const rowSelection = {
selectedRowKeys,
//选择回调
onSelect: (record, selected) => {
if (selected) {
selectedProduct.push(record);
this.setState({selectedProduct})
} else {
selectedProduct.forEach((product, index) => {
if (product.productId === record.productId) {
selectedProduct.splice(index, 1)
}
})
}
},
//全选回调
onSelectAll: (selected, selectedRows, changeRows) => {
if (selected) {
this.setState({selectedProduct: selectedRows})
} else {
this.setState({selectedProduct: []})
}
},
onChange: this.onSelectChange
};
return (
<>
<Modal
title="添加产品"
visible={addModelShow}
footer={null}
onCancel={this.handleCancel}
>
<Add add={add} hideModel={this.handleCancel}/>
</Modal>
<Modal
title="更新产品"
visible={updateModelShow}
footer={null}
onCancel={this.handleCancel}
>
<Update oneProduct={oneProduct} hideModel={this.handleCancel} update={update}/>
</Modal>
<PageHeaderWrapper>
<Card>
<Query onClick={query}/>
<Button type="primary" onClick={this.showAddModel}>添加</Button>
<Button type="danger" onClick={() => this.handleClickBatchDel()}>批量删除</Button>
<Table
dataSource={productList}
rowSelection={rowSelection}
size={'small'}
columns={this.columns}
/>
</Card>
</PageHeaderWrapper>
</>
);
}
}
export default connect(
({product}) =>
({product}),
(dispatch) => {
return {
add: (payload) => dispatch({
type: 'product/add',
payload
}),
getProductList: (payload) => dispatch({
type: 'product/getProductList',
payload
}),
update: (payload) => dispatch({
type: 'product/update',
payload
}),
delete: (payload) => dispatch({
type: 'product/delete',
payload
}),
batchDelete: (payload) => dispatch({
type: 'product/batchDelete',
payload
}),
query: (payload) => dispatch({
type: 'product/query',
payload
}),
dispatch
}
}
)(ProductList)
const categoryList = [{"categoryId": "1", "categoryCode": "1001", "categoryName": "干果"}, {
"categoryId": "2",
"categoryCode": "1002",
"categoryName": "零食"
}, {"categoryId": "3", "categoryCode": "1003", "categoryName": "水果"}, {
"categoryId": "4",
"categoryCode": "1004",
"categoryName": "膨化食品"
}, {"categoryId": "5", "categoryCode": "1005", "categoryName": "饼干"}, {
"categoryId": "6",
"categoryCode": "1006",
"categoryName": "糖果"
}]
const Query = (props) => {
const [productId, setProductId] = useState('');
const [productCode, setProductCode] = useState('');
const [productName, setProductName] = useState('');
const [categoryId, setCategoryId] = useState('');
const [status, setStatus] = useState('');
const query = () => {
props.onClick({
productId, productCode, productName, categoryId, status
})
}
const formLayout = {
labelCol: {span: 4},
wrapperCol: {span: 18},
}
return (<div>
<Form layout={"inline"}>
<Form.Item label="产品id">
<Input placeholder="查询的产品id" value={productId} onChange={(e) => setProductId(e.target.value)}/>
</Form.Item>
<Form.Item label="产品编号">
<Input placeholder="查询的产品编号" value={productCode}
onChange={(e) => setProductCode(e.target.value)}/>
</Form.Item>
<Form.Item label="产品名称">
<Input placeholder="查询的产品名称" value={productName}
onChange={(e) => setProductName(e.target.value)}/>
</Form.Item>
<Form.Item label="分类">
<Select
placeholder="请选择分类"
onChange={setCategoryId}
value={categoryId}
>
<Option value=''>--请选择分类--</Option>
{
categoryList.map(item => (<Option value={item.categoryId}>{item.categoryName}</Option>))
}
</Select>
</Form.Item>
<Form.Item label="状态">
<Select
placeholder="请选择状态"
onChange={setStatus}
value={status}
>
<Option value=''>--请选择状态--</Option>
<Option value="1">有效</Option>
<Option value="0">无效</Option>
</Select>
</Form.Item>
<Form.Item>
<Button type="primary" onClick={query}>提交</Button>
</Form.Item>
</Form>
</div>
)
}
Add.jsx
import {Form, Input, Button,Select,message} from 'antd';
import {PageHeaderWrapper} from '@ant-design/pro-layout';
import {connect} from 'dva';
import React from "react";
const Option=Select.Option
const categoryList=[{"categoryId":"1","categoryCode":"1001","categoryName":"干果"},{"categoryId":"2","categoryCode":"1002","categoryName":"零食"},{"categoryId":"3","categoryCode":"1003","categoryName":"水果"},{"categoryId":"4","categoryCode":"1004","categoryName":"膨化食品"},{"categoryId":"5","categoryCode":"1005","categoryName":"饼干"},{"categoryId":"6","categoryCode":"1006","categoryName":"糖果"}]
const formLayout={
labelCol: { span: 4 },
wrapperCol: { span: 18 },
}
class ProductAdd extends React.Component {
state = {
productCode: '',
productId: '',
productName: '',
categoryId: '',
categoryName: '',
unit: '',
unitPrice: '',
spec: '',
status:''
}
/**
* select改变事件
* @param e
*/
handleSelectChange=(categoryId)=>{
let find = categoryList.find(item=>item.categoryId===categoryId);
if (find){
this.setState({
categoryId,
categoryName:find.categoryName
})
}
}
/**
* 状态下拉列表改变事件
* @param e
*/
handleSelectChangeStatus=(status)=>{
this.setState({status})
}
handleClickSubmit=(e)=>{
const { form: { validateFields },add,hideModel } = this.props; //引入validateFields方法
console.log(Object.keys(this.state))
validateFields(Object.keys(this.state),(err, values) => {
if (err) return;
add({...this.state})
message.success('添加成功')
hideModel()
});
}
/**
* 处理输入框事件
* @param type
* @param val
*/
handleChangeInput=(type,val)=>{
this.setState({
[type]:val
})
}
render() {
const {productCode,productName,productId,categoryId,categoryName,unit,unitPrice,spec,status}= this.state;
const { getFieldDecorator } = this.props.form;
return (
<Form layout="horizontal">
<Form.Item label="产品id" {...formLayout}>
{getFieldDecorator('productId', {
rules: [{ required: true, message: '产品id不能为空'}],
})(<Input placeholder="请输入产品id" initialValue={productId} onChange={(e)=>this.handleChangeInput('productId',e.target.value)} />)}
</Form.Item>
<Form.Item label="产品编码" {...formLayout}>
{getFieldDecorator('productCode', {
rules: [{ required: true, message: '产品编码不能为空' }],
})(<Input placeholder="请输入产品编码" initialValue={productCode} onChange={(e)=>this.handleChangeInput('productCode',e.target.value)} />)}
</Form.Item>
<Form.Item label="产品名称" {...formLayout}>
{getFieldDecorator('productName', {
rules: [{ required: true, message: '产品名称不能为空' }],
})(<Input placeholder="请输入产品名称" initialValue={productName} onChange={(e)=>this.handleChangeInput('productName',e.target.value)} />)}
</Form.Item>
<Form.Item label="计量单位" {...formLayout}>
{getFieldDecorator('unit', {
rules: [{ required: true, message: '计量单位计量单位' }],
})(<Input placeholder="计量单位" initialValue={unit} onChange={(e)=>this.handleChangeInput('unit',e.target.value)}/>)}
</Form.Item>
<Form.Item label="单价" {...formLayout}>
{getFieldDecorator('unitPrice', {
rules: [{ required: true, message: '单价不能为空' }],
})(<Input placeholder="计量单位不能为空" initialValue={unitPrice} onChange={(e)=>this.handleChangeInput('unitPrice',e.target.value)}/>)}
</Form.Item>
<Form.Item label="分类" {...formLayout}>
{getFieldDecorator('categoryId', {
rules: [{ required: true, message: '请选择分类' }],
})(
<Select
placeholder="请选择分类"
onChange={this.handleSelectChange}
>
{
categoryList.map(item=>(<Option value={item.categoryId}>{item.categoryName}</Option>))
}
</Select>,
)}
</Form.Item>
<Form.Item label="状态" {...formLayout}>
{getFieldDecorator('status', {
rules: [{ required: true, message: '请选择状态' }],
})(
<Select
placeholder="请选择状态"
onChange={this.handleSelectChangeStatus}
>
<Option value="1">有效</Option>
<Option value="0">无效</Option>
</Select>,
)}
</Form.Item>
<Form.Item>
<Button type='primary' block onClick={this.handleClickSubmit}>确认添加</Button>
</Form.Item>
</Form>)
}
}
export default Form.create({ name: 'productAdd' })(ProductAdd);
update.jsx
import {Form, Input, Button,Select,message} from 'antd';
import {PageHeaderWrapper} from '@ant-design/pro-layout';
import {connect} from 'dva';
import React from "react";
const Option=Select.Option
const categoryList=[{"categoryId":"1","categoryCode":"1001","categoryName":"干果"},{"categoryId":"2","categoryCode":"1002","categoryName":"零食"},{"categoryId":"3","categoryCode":"1003","categoryName":"水果"},{"categoryId":"4","categoryCode":"1004","categoryName":"膨化食品"},{"categoryId":"5","categoryCode":"1005","categoryName":"饼干"},{"categoryId":"6","categoryCode":"1006","categoryName":"糖果"}]
const formLayout={
labelCol: { span: 4 },
wrapperCol: { span: 18 },
}
class ProductUpdate extends React.Component {
state = {
productCode: '',
productId: '',
productName: '',
categoryId: '',
categoryName: '',
unit: '',
unitPrice: '',
spec: '',
status:''
}
componentDidMount() {
console.log(this.props)
this.setState({
...this.props.oneProduct
})
}
/**
* select改变事件
* @param e
*/
handleSelectChange=(categoryId)=>{
let find = categoryList.find(item=>item.categoryId===categoryId);
if (find){
this.setState({
categoryId,
categoryName:find.categoryName
})
}
}
/**
* 状态下拉列表改变事件
* @param e
*/
handleSelectChangeStatus=(status)=>{
this.setState({status})
}
handleClickSubmit=(e)=>{
console.log(this.state)
const { form: { validateFields },update ,hideModel} = this.props; //引入validateFields方法
console.log(Object.keys(this.state))
validateFields(Object.keys(this.state),(err, values) => {
if (err) return;
update({...this.state});
message.success('更新成功')
hideModel();
});
}
/**
* 处理输入框事件
* @param type
* @param val
*/
handleChangeInput=(type,val)=>{
this.setState({
[type]:val
})
}
render() {
const {productCode,productName,productId,categoryId,categoryName,unit,unitPrice,spec,status}= this.state;
const { getFieldDecorator } = this.props.form;
return (
<Form>
<Form.Item label="产品id" {...formLayout}>
{getFieldDecorator('productId', {
rules: [{ required: true, message: '产品id不能为空'}],
initialValue:productId,
})(<Input placeholder="请输入产品id" onChange={(e)=>this.handleChangeInput('productId',e.target.value)} />)}
</Form.Item>
<Form.Item label="产品编码" {...formLayout}>
{getFieldDecorator('productCode', {
rules: [{ required: true, message: '产品编码不能为空' }],
initialValue:productCode,
})(<Input placeholder="请输入产品编码" onChange={(e)=>this.handleChangeInput('productCode',e.target.value)} />)}
</Form.Item>
<Form.Item label="产品名称" {...formLayout}>
{getFieldDecorator('productName', {
initialValue:productName,
rules: [{ required: true, message: '产品名称不能为空' }],
})(<Input placeholder="请输入产品名称" onChange={(e)=>this.handleChangeInput('productName',e.target.value)} />)}
</Form.Item>
<Form.Item label="计量单位" {...formLayout}>
{getFieldDecorator('unit', {
rules: [{ required: true, message: '计量单位计量单位' }],
initialValue:unit,
})(<Input placeholder="计量单位" onChange={(e)=>this.handleChangeInput('unit',e.target.value)}/>)}
</Form.Item>
<Form.Item label="单价" {...formLayout}>
{getFieldDecorator('unitPrice', {
rules: [{ required: true, message: '单价不能为空' }],
initialValue:unitPrice,
})(<Input placeholder="计量单位不能为空" onChange={(e)=>this.handleChangeInput('unitPrice',e.target.value)}/>)}
</Form.Item>
<Form.Item label="分类" {...formLayout}>
{getFieldDecorator('categoryId', {
initialValue:categoryId,
rules: [{ required: true, message: '请选择分类' }],
})(
<Select
placeholder="请选择分类"
onChange={this.handleSelectChange}
>
{
categoryList.map(item=>(<Option value={item.categoryId}>{item.categoryName}</Option>))
}
</Select>,
)}
</Form.Item>
<Form.Item label="状态" {...formLayout}>
{getFieldDecorator('status', {
rules: [{ required: true, message: '请选择状态' }],
initialValue:status,
})(
<Select
placeholder="请选择状态"
onChange={this.handleSelectChangeStatus}
>
<Option value="1">有效</Option>
<Option value="0">无效</Option>
</Select>,
)}
</Form.Item>
<Form.Item>
<Button type='primary' block onClick={this.handleClickSubmit}>确认添加</Button>
</Form.Item>
</Form>)
}
}
export default Form.create({ name: 'productAdd' })(ProductUpdate);
2.在config/config.js里面配置路由
3.创建model
相应的model代码
import {getProductList} from "@/services/product";
import {productList} from '../../mock/data'
const Model = {
namespace: 'product',
state: {
productList: []
},
effects: {
* getProductList({payload}, {call, put}) {
const response = yield call(getProductList, {});
yield put({
type: 'productList',
payload: productList,
});
},
},
reducers: {
//查询
query(state, {payload: product}){
const {productId,productName,productCode,categoryId,status} =product;
let productList_=productList;
if (productId){
productList_=productList_.filter(item=>item.productId.includes(productId))
}
if (productName){
productList_=productList_.filter(item=>item.productName.includes(productName))
}
if (productCode){
productList_=productList_.filter(item=>item.productCode.includes(productCode))
}
if (categoryId){
productList_=productList_.filter(item=>item.categoryId===categoryId)
}
if (status===0||status){
debugger
productList_=productList_.filter(item=>item.status===status)
}
console.log(product)
return {...state, productList:productList_}
},
productList(state, {payload: productList}) {
return {...state, productList}
},
//添加
add(state, {payload: product}) {
const {productList} = state;
productList.push(product);
return {...state, product}
},
//添加
delete(state, {payload: productId}) {
const {productList} = state;
//删除
productList.forEach((item, index) => {
if (item.productId === productId) {
debugger
productList.splice(index, 1);
return
}
})
return {...state, productList}
},
//添加
update(state, {payload: product}) {
const {productList} = state;
//删除
productList.forEach((item, index) => {
if (item.productId === product.productId) {
productList.splice(index, 1, product);
return
}
})
return {...state, productList}
},
//批量删除
batchDelete(state, {payload: productIds}) {
let {productList} = state;
if (productIds) {
productList=productList.filter((item) => !productIds.includes(item.productId))
}
return {...state, productList}
}
},
subscriptions: {
},
};
export default Model;
4.然后用connect关联组件使用reducer
5.项目演示
添加界面
点击添加按钮,即可把数据添加到全局状态树上
2.更新
产品对应的编辑按钮,弹出编辑框,如图
点击修改按钮后,原来的值被修改
3.删除
点击产品对应的批量删除按钮
点击确认后,我们看到该产品以被删除,看不到了
4.批量删除
勾选想要删除的产品,然后点击批量更新按钮
点击确认按钮,就把这一页的数据删除了
5.查询
输入查询信息
即可把符合条件的查询出来
总结
1.在pages创建页面
2.在config配置路由
3.创建model,namespace取个名,写好reducer和effect和初始state
4.如果要用到远程加载数据,就再services写相关的api请求接口,然后effect里面调用异步api
5.页面关联全局state