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