這裏用到的antd v3 版本的antd
從antd的使用入手:
class NormalLoginForm extends React.Component {
handleSubmit = e => {
e.preventDefault();
this.props.form.validateFields((err, values) => {
if (!err) {
console.log("Received values of form: ", values);
}
});
};
render() {
const { getFieldDecorator } = this.props.form;
return (
<Form onSubmit={this.handleSubmit} className="login-form">
<Form.Item>
{getFieldDecorator("userName",
{ rules: [{ required: true, message: "Please input your username!" }] })
(
<Input prefix={<Icon type="user" style={{ color: "rgba(0,0,0,.25)" }} />}
placeholder="Username"/>
)}
</Form.Item>
<Form.Item>
{getFieldDecorator("password",
{ rules: [{ required: true, message: "Please input your password!" }] })
(
<Input prefix={<Icon type="lock" style={{ color: "rgba(0,0,0,.25)" }} />}
placeholder="Password"/>
)}
</Form.Item>
<Form.Item>
<Button type="primary" htmlType="submit" className="login-form-button">login</Button>
</Form.Item>
</Form>
)
}
}
const WrappedNormalLoginForm = Form.create({ name: "normal_login" })( NormalLoginForm );
Form.create 幹了些什麼?
- getFieldDecorator: 字段裝飾器 給輸入框強化功能: name字段, 驗證規則, 這其中肯定用到了input的 onChange方法
- validateFields: 根據規則來驗證所有的輸入項
表單設計
擴展表單的高階組件,提供輸入控件包裝、事件處理、表單校驗等
form.create的簡單實現
function MyFormCreate(Comp) {
return class extends React.Component {
constructor(props) {
super(props);
this.options = {};
this.state = {};
}
//處理輸入事件,輸入中進行校驗
handleChange = e => {
let { name, value } = e.target;
this.setState({
[name]: value
}, () => {
this.validateField(name)
})
}
//驗證所有字段, 將結果傳入回調函數,且調用回調函數
validate = (cb) => {
let isValidated = true
Object.keys(this.options).forEach(field => {
isValidated = this.validateField(field)
})
cb && cb(isValidated)
}
//驗證單個字段
validateField(field) {
let flag = true,
{rules} = this.options[field]
rules.some(rule => {
if(rule.required) {
let msg = !this.state[field] && rule.message
this.setState({
[field+'errorMsg']: msg
})
flag = false
return false
}
})
return flag
}
//字段裝飾器
getFieldDec = (field, option) => {
this.options[field] = option
return InputComp => (
<div>
{React.cloneElement(InputComp, {
name: field,
value: this.state[field] || "",
onChange: this.handleChange
})}
{/* 校驗信息 */}
{this.state[field+'errorMsg']&&(<p style={{color: 'red'}}>{this.state[field+'errorMsg']}</p>)}
</div>
)
}
//將getFieldDec和validate 掛載到新組件中
render() {
return (
<div>
<Comp {...this.props} getFieldDec={this.getFieldDec} validate={this.validate} />
</div>
)
}
}
}
使用
@MyFormCreate
class MyFormTest extends React.Component{
onSubmit = () => {
this.props.validate(flag => {
console.log(flag)
})
}
render() {
let {getFieldDec} = this.props
return (
<div>
{getFieldDec('username', {
rules: [{required: true, message: '請輸入用戶名'}]
})(<input type="text" />)}
{getFieldDec('password', {
rules: [{required: true, message: '請輸入密碼'}]
})(<input type="password" />)}
<button onClick={this.onSubmit}>登錄</button>
</div>
)
}
}