前言:以下內容基於React全家桶+AntD實戰課程的學習實踐過程記錄。最終成果github地址:https://github.com/66Web/react-antd-manager,歡迎star。
一、使用Form組件開發登錄頁面

- pages->form->login.js:對應路由/admin/form/login
import React from 'react'
import {Card, Form, Input, Button, message, Icon, Checkbox} from 'antd'
const FormItem = Form.Item
class FormLogin extends React.Component{
handleSubmit = () => {
let userInfo = this.props.form.getFieldsValue();
this.props.form.validateFields((err, values) => {
if(!err){
message.success(`${userInfo.userName} 恭喜你,您通過本次表單組件學習,當前密碼為:${userInfo.userPwd}`)
}
})
}
render(){
const { getFieldDecorator } = this.props.form;
return (
<div>
<Card title="登錄行內表單">
<Form layout="inline">
<FormItem>
<Input placeholder="請輸入用戶名"/>
</FormItem>
<FormItem>
<Input placeholder="請輸入密碼"/>
</FormItem>
<FormItem>
<Button type="primary">登錄</Button>
</FormItem>
</Form>
</Card>
<Card title="登錄水平表單" style={{marginTop:10}}>
<Form layout="horizontal" style={{width:300}}>
<FormItem>
{
getFieldDecorator('userName', {
initialValue:'Elena',
rules:[
{
required: true,
message:'用戶名不能為空'
},
{
min:5, max:10,
message: '長度不在范圍內'
},
{
pattern: new RegExp('^\\w+$','g'),
message: '用戶名必須為字母或數字'
}
]
})(
<Input prefix={<Icon type="user"/>} placeholder="請輸入用戶名"/>
)
}
</FormItem>
<FormItem>
{
getFieldDecorator('userPwd', {
initialValue:'123456',
rules:[
{
required: true,
message:'密碼不能為空'
},
{
min:6, max:8,
message: '長度不在范圍內'
}
]
})(
<Input prefix={<Icon type="lock"/>} type="password" placeholder="請輸入密碼"/>
)
}
</FormItem>
<FormItem>
{
getFieldDecorator('remember', {
valuePropName: 'checked',
initialValue: true,
})(
<Checkbox>記住密碼</Checkbox>
)
}
<a href="#" style={{float:'right'}}>忘記密碼</a>
</FormItem>
<FormItem>
<Button type="primary" onClick={this.handleSubmit}>登錄</Button>
</FormItem>
</Form>
</Card>
</div>
)
}
}
export default Form.create()(FormLogin);
- Form組件
- layout屬性:表示表單布局 -- inline行內表單/horizontal水平表單
- getFieldDecorator屬性:幫助進行初始化值,獲取數據
- getFieldDecorator(‘表單里的一些對象’,定義的規則和值)(組件)
{ getFieldDecorator('userName', { initialValue:'Elena', rules:[ { required: true, message:'用戶名不能為空' }, { min:5, max:10, message: '長度不在范圍內' }, { pattern: new RegExp('^\\w+$','g'), message: '用戶名必須為字母或數字' } ] })( <Input prefix={<Icon type="user"/>} placeholder="請輸入用戶名"/> ) }需要在組件最下方添加 ↓:(經過
Form.create包裝的組件將會自帶this.props.form屬性)export default Form.create()(FormLogin);
-
prefix屬性:加前綴,使用Icon組件添加小圖標
<Input prefix={<Icon type="user"/>} placeholder="請輸入用戶名"/> -
指定表單的寬度
style={{width:300}} - 設置記住密碼框默認選中
{ getFieldDecorator('remember', { valuePropName: 'checked', initialValue: true, })( <Checkbox>記住密碼</Checkbox> ) }
- options.rules校驗規則
- required:是否必選
- min : 最小長度
- max : 最大長度
- len : 字段長度
- partten : 正則表達式
- type: 內建校驗類型 類型選項
二、使用Form組件開發注冊頁面

- pages->form->register.js:對應路由/admin/form/reg
import React from 'react'
import moment from 'moment'
import {Card,Form,Input,Button,Checkbox,Radio,InputNumber,Select,Switch,DatePicker,TimePicker,Upload,Icon,message} from 'antd'
const FormItem = Form.Item
const RadioGroup = Radio.Group
const Option = Select.Option;
const TextArea = Input.TextArea
class FormRegister extends React.Component {
state = {
loading: false,
};
handleSubmit = () => {
let userInfo = this.props.form.getFieldsValue();
console.log(JSON.stringify(userInfo))
message.success(`${userInfo.userName} 恭喜你,您通過本次表單組件學習,當前密碼為:${userInfo.userPwd}`)
}
handleResetInfo = () => {
this.props.form.resetFields();
}
//模擬上傳jpg -- 直接從官網復制過來即可
getBase64 = (img, callback) => {
const reader = new FileReader();
reader.addEventListener('load', () => callback(reader.result));
reader.readAsDataURL(img);
}
handleChange = (info) => {
if (info.file.status === 'uploading') {
this.setState({ loading: true });
return;
}
if (info.file.status === 'done') {
// Get this url from response in real world.
this.getBase64(info.file.originFileObj, imageUrl => this.setState({
userImg: imageUrl,
loading: false,
}));
}
}
render(){
const { getFieldDecorator } = this.props.form;
const formItemLayout = {
labelCol: {
xs: 24,
sm: 4
},
wrapperCol: {
xs: 24,
sm: 12
}
}
const offsetLayout = {
wrapperCol: {
xs: 24,
sm: {
span:12,
offset:4
}
}
}
const rowObject = {
minRows: 4,
maxRows: 6
}
return (
<div>
<Card title="注冊表單">
<Form layout="horizontal">
<FormItem label="用戶名" {...formItemLayout}>
{
getFieldDecorator('userName', {
initialValue:'Elena',
rules:[
{
required: true,
message:'用戶名不能為空'
}
]
})(
<Input placeholder="請輸入用戶名"/>
)
}
</FormItem>
<FormItem label="密碼" {...formItemLayout}>
{
getFieldDecorator('userPwd', {
initialValue:'123456',
rules:[
{
required: true,
message:'密碼不能為空'
}
]
})(
<Input type="password" placeholder="請輸入密碼"/>
)
}
</FormItem>
<FormItem label="性別" {...formItemLayout}>
{
getFieldDecorator('sex', {
initialValue:'1'
})(
<RadioGroup>
<Radio value="1">女</Radio>
<Radio value="2">男</Radio>
</RadioGroup>
)
}
</FormItem>
<FormItem label="年齡" {...formItemLayout}>
{
getFieldDecorator('age', {
initialValue:'18'
})(
<InputNumber />
)
}
</FormItem>
<FormItem label="當前狀態" {...formItemLayout}>
{
getFieldDecorator('state', {
initialValue:'1'
})(
<Select>
<Option value="1">咸魚一條</Option>
<Option value="2">人民公仆</Option>
<Option value="3">浙傳才女一枚</Option>
<Option value="4">科技公司FE</Option>
<Option value="5">創業者</Option>
</Select>
)
}
</FormItem>
<FormItem label="愛好" {...formItemLayout}>
{
getFieldDecorator('state', {
initialValue:['1','3','5']
})(
<Select mode="multiple">
<Option value="1">旅行</Option>
<Option value="2">讀書</Option>
<Option value="3">剪輯</Option>
<Option value="4">拍照</Option>
<Option value="5">看電影</Option>
</Select>
)
}
</FormItem>
<FormItem label="是否已婚" {...formItemLayout}>
{
getFieldDecorator('isMarried', {
valuePropName: 'checked',
initialValue: true
})(
<Switch />
)
}
</FormItem>
<FormItem label="生日" {...formItemLayout}>
{
getFieldDecorator('birthday', {
initialValue: moment('2019-1-1 11:14:59')
})(
<DatePicker
showTime
format="YYYY-MM-DD HH:mm:ss"
/>
)
}
</FormItem>
<FormItem label="聯系地址" {...formItemLayout}>
{
getFieldDecorator('address',{
initialValue: '西虹市海淀區桃花公園'
})(
<TextArea
autosize={rowObject}
/>
)
}
</FormItem>
<FormItem label="早起時間" {...formItemLayout}>
{
getFieldDecorator('time')(
<TimePicker />
)
}
</FormItem>
<FormItem label="頭像" {...formItemLayout}>
{
getFieldDecorator('userImg')(
<Upload
listType="picture-card"
showUploadList={false}
action="//jsonplaceholder.typicode.com/posts/"
onChange={this.handleChange}
>
{this.state.userImg?<img src={this.state.userImg}/>:<Icon type="plus"/>}
</Upload>
)
}
</FormItem>
<FormItem {...offsetLayout}>
{
getFieldDecorator('imooc')(
<Checkbox>我已閱讀過<a href="#">慕課協議</a></Checkbox>
)
}
</FormItem>
<FormItem {...offsetLayout}>
<Button type="primary" onClick={this.handleSubmit}>提交</Button>
<Button style={{marginLeft:10}} onClick={this.handleResetInfo}>重置</Button>
</FormItem>
</Form>
</Card>
</div>
)
}
}
export default Form.create()(FormRegister);
- Form支持響應式尺寸
//Form組件內嵌的柵格布局 const formItemLayout = { labelCol: { xs: 24, sm: 4 }, wrapperCol: { xs: 24, sm: 12 } } //偏移布局 const offsetLayout = { wrapperCol: { xs: 24, sm: { span:12, offset:4 //向右偏移4列 } } } -
數字框:
<InputNumber/> -
時間類組件: DatePicker
value類型為moment對象,所以在提交服務器前需要預處理-
安裝moment
yarn add moment --save
-
引用moment
import moment from "moment"; …… <FormItem label="生日" {...formItemLayout}> { getFieldDecorator('birthday', { initialValue: moment('2019-1-1 11:14:59') })( <DatePicker showTime format="YYYY-MM-DD HH:mm:ss" /> ) } </FormItem>
-
獲取表單中Object對象
-
調用getFieldsValue方法:獲取一組輸入控件的值,如不傳入參數,則獲取全部組件的值
let userInfo = this.props.form.getFieldsValue();
-
重置表單內容:調用resetFields方法
this.props.form.resetFields()
-
注意:使用
getFieldsValue、getFieldValue、setFieldsValue等時,需要確保對應的 field 已經用getFieldDecorator注冊過了 -
其它Api:官網文檔
- 上傳文件類組件:Upload
- action屬性:上傳的服務器地址
- listType屬性:上傳列表的內建樣式
text/picture/picture-card - showUploadList屬性:是否展示上傳列表內容 {false}↑ 或{true}↓

- onChange屬性:上傳文件狀態改變的回調,詳見 onChange
- 使用Upload組件必需的幾個方法:
//模擬上傳jpg -- 直接從官網復制過來即可 getBase64 = (img, callback) => { const reader = new FileReader(); reader.addEventListener('load', () => callback(reader.result)); reader.readAsDataURL(img); } handleChange = (info) => { if (info.file.status === 'uploading') { this.setState({ loading: true }); return; } if (info.file.status === 'done') { // Get this url from response in real world. this.getBase64(info.file.originFileObj, imageUrl => this.setState({ userImg: imageUrl, loading: false, })); } }
注:項目來自慕課網
