1.Antd表单封装的字段包装:
这里简单梳理下整个执行过程思路,方便日后复习:
MFormCreate
组件作为装饰器,包装MForm
- 通过解构赋值
const {getFieldDecorator} = this.props.form;
获得了MFromCreate
传递的form对象(键值对的value是函数)
getFieldDecorator
函数是一个高阶函数
,返回的函数接收一个Jsx
React.cloneElement()
:克隆并返回一个新的ReactElement
(内部子元素也会跟着克隆),接收3个参数
- 参数①:用于克隆的母体React元素(必选)
- 参数②:为克隆后生成的React元素添加新的props,或覆盖从母体中克隆而来的部分或全部props。(可选)
- 参数③:为新生成的React元素添加新的children,取代从母体中克隆而来的children
- 然后执行到
onChange
事件 - 接着,在
onChange
事件绑定的handleChange
方法中修改state状态值
- 在
setState
函数参数的第二个参数的函数中去对最新修改修改的值做校验
// MformCreate.js
import React, {Component} from 'react';
const MFormCreate = Comp =>{
return class extends Component{
constructor(props) {
super(props);
this.options = {};// 各个字段的选项值 它的变化不会影响组件的重新渲染
this.state = {}; // 各个字段的值 他的变化 要触发校验的函数
this.form = this.form.bind(this);
this.getFieldDecorator = this.getFieldDecorator.bind(this);
this.handleChange = this.handleChange.bind(this);
this.validateFiled = this.validateFiled.bind(this);
}
//处理表单项的输入事件
handleChange(e){
const {name,value} = e.target;
console.log("我是name:",name,"我是值",value);
this.setState({
[name]:value
},()=>{
//🚀 设置完之后要校验各个字段
this.validateFiled(name);
})
}
// 🌟 校验(下面会重新提及)
validateFiled(filedName){
console.log("校验啦",filedName);
}
// 🚀 getFieldDecorator返回一个函数
getFieldDecorator(filedName,options){
//设置字段选项的配置
this.options[filedName] = options;
return (Jsx)=>{
//🚀这里使用一种更加api的方式
return (
<div>
{
//两个参数:①要克隆的元素;②对象属性
React.cloneElement(Jsx,{
name:filedName,//控件的name
value:this.state[filedName] || "", //控件的值
onChange:this.handleChange
})
}
</div>
)
}
}
//🚀 这里form函数调用后返回一个函数组成的对象,后续若有添加,拓展这个返回的对象即可
form(){
return(
{
getFieldDecorator:this.getFieldDecorator
}
)
}
render() {
return (
<Comp {...this.props} form = {this.form()}> </Comp>
)
}
}
}
//MForm.js
import React, {Component} from 'react';
import MFormCreate form "./Compontent";
@MFormCreate
class MForm extends Component {
constructor(props) {
super(props);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleSubmit(){
// 校验各个字段的必填项是否正确
}
render() {
const {getFieldDecorator} = this.props.form;
return (
<div>
{
getFieldDecorator("username",{
rules:[
{
required:true,
message:"用户名为必填项目"
}
]
})( <input type="text"/>)
}
{
getFieldDecorator("password",{
rules:[
{
required:true,
message:"密码为必填项目"
}
]
})( <input type="password"/>)
}
{/*<input type="text"/>*/}
{/*<input type="password"/>*/}
<input type="button" value="登录" onClick={this.handleSubmit}/>
</div>
);
}
}
export default MForm;
2.表单的单独项的校验:
getFieldDecorator
函数中通过this.options[filedName] = options;
完成对this.options对象的赋值,这个地方比较精髓handleChange
中将输入的值作为参数传递给validateFiled
中进行校验validateFiled
函数中对this.options
解构,然后利用规则进行判断。
// validateFiled函数
//...
validateFiled(filedName){
console.log("校验啦",filedName);
const {rules} = this.options[filedName];
const ret = rules.some(rule=>{
//🚀 required为true时则需要校验
if(rule.required){
// 如果input的输入框没有值,设置显示的rule.message文字进行提示
if(!this.state[filedName]){
this.setState({
[filedName + "Message"]:rule.message
})
return true; //校验失败 返回true
}
}
})
if(!ret){
this.setState({
[filedName + "Message"]:""
})
}
return !ret; //校验成功 返回false
}
//...
3.表单提交按钮校验的实现方法:
- 从
hanldeSubmit
方法开始看,返回的form对象中新添加了validateFields
方法,用于校验提交按钮 - 通过
Object.keys(this.options)
拿到想要的key值组成的数组后,对每项进行单项的校验--validateFiled
- 最后将校验结果通过
callback
回调函数传递回去 true
弹出成功的tips
,false
弹出失败的tips
//MFromCreate.js
import React, {Component} from 'react';
const MFormCreate = Comp =>{
return class extends Component{
constructor(props) {
super(props);
this.options = {};//各个字段的选项值 它的变化不会影响组件的重新渲染
this.state = {}; //各个字段的值 他的变化 要触发校验的函数
this.form = this.form.bind(this);
this.getFieldDecorator = this.getFieldDecorator.bind(this);
this.handleChange = this.handleChange.bind(this);
this.validateFiled = this.validateFiled.bind(this);
this.validateFileds = this.validateFileds.bind(this);
}
//处理表单项的输入事件
handleChange(e){
const {name,value} = e.target;
console.log("我是name:",name,"我是值",value);
//setState是异步的
this.setState({
[name]:value
},()=>{
//🚀设置完之后要校验各个字段
this.validateFiled(name);
})
}
//🚀 单项目校验
validateFiled(filedName){
console.log("校验啦",filedName);
const {rules} = this.options[filedName];
const ret = rules.some(rule=>{
//🚀 required为true时则需要校验
if(rule.required){
// 如果input的输入框没有值,设置显示的rule.message文字进行提示
if(!this.state[filedName]){
this.setState({
[filedName + "Message"]:rule.message
})
return true;
}
}
})
if(!ret){
this.setState({
[filedName + "Message"]:""
})
}
return !ret;
}
// 🚀 表单提交按钮的校验
validateFileds(callback){
//这个地方需要取到各个字段的值,然后对各个字段进行校验
console.log("测试",Object.keys(this.options))
const rets = Object.keys(this.options).map((filedName)=>{
return this.validateFiled(filedName);
})
//使用数组的every方法,如果所有的单项校验都为true,那么校验通过
const res = rets.every(v=>v===true);
callback(res);
}
//getFieldDecorator返回一个函数
getFieldDecorator(filedName,options){
//设置字段选项的配置
this.options[filedName] = options;
return (Jsx)=>{
//🚀这里使用一种更加api的方式
return (
<div>
{
//两个参数:①要克隆的元素;②对象属性
React.cloneElement(Jsx,{
name:filedName,//控件的name
value:this.state[filedName] || "", //控件的值
onChange:this.handleChange
})
}
{
this.state[filedName + "Message"] && (<p style={{color:'red'}}>{this.state[filedName + "Message"]}</p>)
}
</div>
)
}
}
//这里form函数调用后返回一个函数组成的对象
form(){
return(
{
getFieldDecorator:this.getFieldDecorator,
validateFields:this.validateFileds
}
)
}
render() {
return (
<Comp {...this.props} form = {this.form()}> </Comp>
)
}
}
}
//MForm.js校验
import React, {Component} from 'react';
import MFormCreate form "./Compontent";
@MFormCreate
class MForm extends Component {
constructor(props) {
super(props);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleSubmit(){
// 校验各个字段的必填项是否正确
this.props.form.validateFields((isValid)=>{
if(isValid){
alert("验证成功~!")
}else{
alert("验证失败,请重新输入")
}
})
}
render() {
const {getFieldDecorator} = this.props.form;
return (
<div>
{
getFieldDecorator("username",{
rules:[
{
required:true,
message:"用户名为必填项目"
}
]
})( <input type="text"/>)
}
{
getFieldDecorator("password",{
rules:[
{
required:true,
message:"密码为必填项目"
}
]
})( <input type="password"/>)
}
{/*<input type="text"/>*/}
{/*<input type="password"/>*/}
<input type="button" value="登录" onClick={this.handleSubmit}/>
</div>
);
}
}
export default MForm;
回调函数的用法真的是灰常nice~!︿( ̄︶ ̄)︿