React Ant Design Pro業務代碼編寫反思
一、這幾天,在學習新的react+Ant Design Pro技術,在此記錄一下,有很多想說的,之所以選擇了React,是因爲它是基於組件化,能夠通過組件和狀態控制頁面的數據更新渲染,不得不說受到了很多人的喜愛。但我這兩天寫下來,我完成了一個簡單的功能,頁面如下圖:
二、代碼:
import React from 'react'
import { Button, Card, Col, DatePicker, Form, Table, Row, Select, Modal, Tag, Input, Radio, message } from 'antd'
import { SearchOutlined, PlusSquareOutlined } from '@ant-design/icons';
import { connect } from 'dva';
import moment from 'moment';
const { Item } = Form;
const { Option } = Select;
const columns = [
{
title: "行程",
dataIndex: "lineName",
render: text => <a>{text}</a>,
key: "lineName"
},
{
title: "狀態",
className: "column-money",
dataIndex: "status",
key: "status",
render: (status) => {
return status === 2 ? '正常' : '異常'
}
},
{
title: "行程時間",
dataIndex: "departTime",
key: "departTime"
},
{
title: "剩餘座位",
dataIndex: "seatLeft",
key: "seatLeft",
},
{
title: "車次價格",
dataIndex: "minPrice",
key: "minPrice",
render: (minPrice) => {
return `${minPrice}-${minPrice}`
}
},
{
title: "司機姓名",
dataIndex: "driverName",
key: "driverName"
},
{
title: "車牌號",
dataIndex: "vehicleNo",
key: "vehicleNo"
},
{
title: '操作',
dataIndex: '',
key: 'x',
render: (text, record) => (
<span>
<a style={{ marginRight: 8 }}>編輯{record.name}</a>
<a style={{ marginRight: 8 }}>刪除</a>
</span>
),
},
];
const columns1 = [
{
title: "行程",
dataIndex: "lineName",
render: text => <a>{text}</a>,
key: "lineName"
},
{
title: "行程時間",
dataIndex: "departTime",
key: "departTime"
},
{
title: "司機姓名",
dataIndex: "driverName",
key: "driverName"
},
{
title: "車牌號",
dataIndex: "vehicleNo",
key: "vehicleNo"
}
];
@connect(({ schedule, loading }) => ({
schedule,
listData: schedule.listData,
loading: loading.effects['schedule/querySchedule'],
totalCount: schedule.totalCount,
pageSize: schedule.pageSize,
supplier: schedule.supplier,
trip: schedule.trip,
driver: schedule.driver,
vehicleNumber: schedule.vehicleNumber
}))
export default class UserSearchPage extends React.Component {
state = {
visible: false,
addVisible: false,
selectedRowKeys: [],
selectRowData: [],
listData1: [],
priceState: false
};
componentDidMount() {
this.handleGetListData();
this.supplierList();
this.tripList();
this.driverList();
this.driverList();
this.vehicleNumberList()
};
showModal = () => {
const { selectRowData} = this.state;
if (selectRowData.length == 0) {
message.warning('請先選擇一行數據');
}
else {
this.setState({
visible: true,
listData1: selectRowData
});
}
};
addShowModal = () => {
this.setState({
addVisible: true,
});
};
handleOk = () => {
setTimeout(() => {
this.setState({ visible: false, addVisible: false, selectRowData: [] });
}, 3000);
};
handleCancel = () => {
this.setState({ visible: false, addVisible: false, selectRowData: [] });
};
priceStateChange = (e) => {
if (e.target.value === 1) {
this.setState({ priceState: true });
}
else {
this.setState({ priceState: false });
}
};
// 獲取基本數據列表
handleGetListData = () => {
const { dispatch } = this.props;
dispatch({
type: 'schedule/querySchedule',
payload: { page: 1, limit: 10 },
});
};
supplierList = () => {
const { dispatch } = this.props;
dispatch({
type: 'schedule/querySupplier'
});
};
tripList = () => {
const { dispatch } = this.props;
dispatch({
type: 'schedule/queryTrip'
});
};
driverList = () => {
const { dispatch } = this.props;
dispatch({
type: 'schedule/queryDriver'
});
};
vehicleNumberList = () => {
const { dispatch } = this.props;
dispatch({
type: 'schedule/queryVehicleNumber'
});
};
/**
* 分頁的改變
*/
// 分頁改變
onShowSizeChange = (current, pageSize) => {
const { dispatch } = this.props;
const params = {
page: current,
limit: pageSize,
};
dispatch({
type: 'schedule/querySchedule',
payload: params,
});
};
changePage = (current, pageSize) => {
const { dispatch } = this.props;
const params = {
page: current,
limit: pageSize,
};
dispatch({
type: 'schedule/querySchedule',
payload: params,
})
}
onSelectChange = (selectedRowKeys, selectedRows) => {
// console.log('selectedRowKeys changed: ', selectedRowKeys);
this.setState({ selectedRowKeys, selectRowData: selectedRows });
};
render() {
const { schedule, listData, totalCount, loading } = this.props;
const { visible, selectedRowKeys, addVisible, listData1, priceState } = this.state;
const { RangePicker } = DatePicker;
const dateFormat = 'YYYY-MM-DD';
const rowSelection = {
selectedRowKeys,
onChange: this.onSelectChange,
hideDefaultSelections: true,
};
const { supplier = [], trip = [], driver = [], vehicleNumber = [] } = schedule; // 設置默認爲空,如果不設置默認,第一次render時會報錯
return (
<Card
style={{ marginBottom: '1%' }}
bodyStyle={{ paddingBottom: 0, paddingTop: '3%' }}
>
<Form labelAlign='left'>
<Row gutter={24}>
<Col xs={24} sm={12} md={12} lg={8} xl={6}>
<Item label='供應商:'>
<Select defaultValue="全部" style={{ width: 160 }}>
{supplier.map((item, index) => <Option key={index} value={item.name}>
{item.name}</Option>)}
</Select>
</Item>
</Col>
<Col xs={24} sm={12} md={12} lg={8} xl={6}>
<Item label='司機:'>
<Select defaultValue="全部" style={{ width: 160 }}>
{driver.map((item, index) => <Option key={index} value={item.name}>
{item.name}</Option>)}
</Select>
</Item>
</Col>
<Col xs={24} sm={12} md={12} lg={8} xl={6}>
<Item label='車牌號:'>
<Select defaultValue="全部" style={{ width: 160 }}>
{vehicleNumber.map((item, index) => <Option key={index} value={item.plateNumber}>
{item.plateNumber}</Option>)}
</Select>
</Item>
</Col>
</Row>
<Row gutter={24}>
<Col xs={24} sm={12} md={12} lg={8} xl={6}>
<Item label='日期:'>
<DatePicker onChange={this.onChange} defaultValue={moment()} format={dateFormat} />
</Item>
</Col>
<Col xs={24} sm={12} md={12} lg={8} xl={6}>
<Item label='行程:'>
<Select defaultValue="全部" style={{ width: 160 }}>
{trip.map((item, index) => <Option key={index} value={item.lineName}>
{item.lineName}</Option>)}
</Select>
</Item>
</Col>
<Col xs={24} sm={24} md={24} lg={12} xl={6}>
<Item>
<Button type="primary" icon={<SearchOutlined />} onClick={this.quserSchedule}>
查詢
</Button>
</Item>
</Col>
<Col xs={24} sm={24} md={24} lg={12} xl={6}>
<Item>
<Button icon={<PlusSquareOutlined />} onClick={this.showModal}>
複製車次
</Button>
<Button style={{ marginLeft: 8 }} icon={<PlusSquareOutlined />} onClick={this.addShowModal}>
添加車次
</Button>
</Item>
</Col>
</Row>
</Form>
<Table
rowSelection={rowSelection}
showQuickJumper={false}
columns={columns}
dataSource={listData}
pagination={{
simple: false,
showQuickJumper: true,
showSizeChanger: true,
showTotal: () => `共${totalCount}條`,
total: totalCount,
responsive: true,
onShowSizeChange: this.onShowSizeChange,
onChange: (current, pageSize) => this.changePage(current, pageSize),
}}
// scroll={{ y: 280 }}
loading={loading}
title={() => '排班定價數據列表'}
bordered />
<Modal
visible={visible}
title="複製車次"
onOk={this.handleOk}
onCancel={this.handleCancel}
footer={[
<Button key="back" onClick={this.handleCancel}>
取消
</Button>,
<Button key="submit" type="primary" onClick={this.handleOk}>
複製併發布
</Button>,
]}
>
<Row justify="center">
<Col span={18}> 日期:
<RangePicker /></Col>
</Row>
<br />
<br />
<Table
columns={columns1}
dataSource={listData1}
/>
</Modal>
<Modal
visible={addVisible}
title="添加車次"
onOk={this.handleOk}
onCancel={this.handleCancel}
width={680}
footer={[
<Button key="back" onClick={this.handleCancel}>
取消
</Button>,
<Button key="submit" type="primary" onClick={this.handleOk}>
發佈
</Button>,
]}
>
<Form
name="basic"
initialValues={{
remember: true,
}}
>
<Row justify="space-between">
<Col span={12}>
<Form.Item
label="供 應 商"
name="username"
labelAlign="right"
>
<Select defaultValue="全部" style={{ width: 160 }}>
{supplier.map((item, index) => <Option key={index} value={item.name}>
{item.name}</Option>)}
</Select>
</Form.Item>
<Form.Item
label="生效日期"
name="password"
labelAlign="right"
>
<DatePicker onChange={this.onChange} defaultValue={moment()} format={dateFormat} />
</Form.Item>
</Col>
<Col>
<Form.Item
label="行程"
name="xc"
>
<Select defaultValue="全部" style={{ width: 160 }}>
{trip.map((item, index) => <Option key={index} value={item.lineName}>
{item.lineName}</Option>)}
</Select>
</Form.Item>
<Form.Item
label="司機"
>
<Select defaultValue="全部" style={{ width: 160 }}>
{driver.map((item, index) => <Option key={index} value={item.name}>
{item.name}</Option>)}
</Select>
</Form.Item>
</Col>
</Row>
<Row>
<Col>
<Form.Item
label="價格類型"
name="pricetype"
>
<Radio.Group name="radiogroup" defaultValue={2} onChange={this.priceStateChange}>
<Radio value={1}>自定義</Radio>
<Radio value={2}>統一</Radio>
</Radio.Group>
</Form.Item>
</Col>
</Row>
<Row justify="space-between">
<Col span={12}>
<Form.Item
label="座位原價"
name="xc"
>
<Input />
</Form.Item>
</Col>
<Col>
<Form.Item
label="優惠價"
name="xc"
>
<Input />
</Form.Item>
</Col>
</Row>
<Row justify="center">
<Col>
<Tag color="red">說明:優惠價=座位最終票價,原件與優惠價相等時,前端只展示優惠價!</Tag>
</Col>
</Row>
<br />
{
priceState ? (
<Card>
<Row>
<Col span={8}>
<Form.Item
label="司機位"
name="sjw"
>
<Input />
</Form.Item>
</Col>
<Col span={8} offset={8}>
<Form.Item
label="副駕"
name="fj"
>
<Input />
</Form.Item>
</Col>
<Col span={8} offset={16}>
<Form.Item
label="原價"
name="yj"
>
<Input />
</Form.Item>
</Col>
<Col span={8} offset={16}>
<Form.Item
label="優惠價"
name="yhj"
>
<Input />
</Form.Item>
</Col>
</Row>
<Row>
<Col span={8}>
<span>二排左:</span>
</Col>
<Col span={8} offset={8}>
<span>二排右:</span>
</Col>
</Row>
<br/>
<Row>
<Col span={8} >
<Form.Item
label="原價"
name="yj"
>
<Input />
</Form.Item>
<Form.Item
label="優惠價"
name="yhj"
>
<Input />
</Form.Item>
</Col>
<Col span={8} offset={8}>
<Form.Item
label="原價"
name="yj"
>
<Input />
</Form.Item>
<Form.Item
label="優惠價"
name="yhj"
>
<Input />
</Form.Item>
</Col>
</Row>
<Row>
<Col span={6}>
<span>三排左:</span>
</Col>
<Col span={6} offset={3}>
<span>三排中:</span>
</Col>
<Col span={6} offset={3}>
<span>三排右:</span>
</Col>
</Row>
<br/>
<Row gutter={8}>
<Col span={6} >
<Form.Item
label="原價"
name="yj"
>
<Input />
</Form.Item>
<Form.Item
label="優惠價"
name="yhj"
>
<Input />
</Form.Item>
</Col>
<Col span={6} offset={3}>
<Form.Item
label="原價"
name="yj"
>
<Input />
</Form.Item>
<Form.Item
label="優惠價"
name="yhj"
>
<Input />
</Form.Item>
</Col>
<Col span={6} offset={3}>
<Form.Item
label="原價"
name="yj"
>
<Input />
</Form.Item>
<Form.Item
label="優惠價"
name="yhj"
>
<Input />
</Form.Item>
</Col>
</Row>
</Card>
) : null
}
</Form>
</Modal>
</Card>
);
}
}
三、分析
1、完成上面圖片上的效果,我都是在同一個jsx文件裏面寫的(思考:這裏是不是與React設計思想背離了呢?沒有任何外部組件的引用,那這些代碼,就只能在這個頁面使用,在其它地方顯得沒有任何用處,所以我打算重寫了)
2、這一個頁面,我現在只是單單寫了頁面代碼,並沒有太多的業務邏輯(增刪改的邏輯都還沒寫呢,肯定又是要加一些亂七八糟狀態,控制數據和頁面的渲染),然而現在的代碼已經591行了,想想,的確多的有點離譜了,所以一直有個想法在我腦海裏打轉,是不是我真的理解錯了React,看來得去好好看看視頻,在次深入理解一下。
ps:這裏只是我一時得敢想,在這裏做個記錄,如果哪位是這方面技術得大佬,能否給我指點一下,讓我少走些彎路吧!
聯繫方式:QQ:1798274010
編寫人:洪偉富(小洪同學。。。)