【React实践总结】Form表单即时校验输入值(基于Antd Design)

1.判断输入值的长度

1.1 根据输入值的类型不同,限制输入值长度不同
此时需要使用自定义的校验规则。 如长度要求:中文输入5位,非中文10位

<FormItem label="名称" {...formItemLayout}>
 2     {getFieldDecorator('name', {
 3         rules: [
 4             {
 5                 required: true,
 6                 message: "名称不能为空",                                           
 7             },                    
 8             {
 9                 validator: async (rule, value, callback) => {
10                     const reg = new RegExp("[\\u4E00-\\u9FFF]+","g"); //正则校验
11                     if(reg.test(value) && value.length > 5){
12                         callback("中文最多5位");
13                     }else if(value.length > 10){
14                         callback("非中文最多10位");
15                     } else{
16                         callback();
17                     }                                                                                            
18                 }
19             }
20         ],
21     })(
22         <Input placeholder="这里输入名称" allowClear />,
23     )}
24 </FormItem>

1.2 不对输入类型做区分,统一设置长度
如:

输入值长度最少5位,最大10位; 使用现有规则:min ,max
长度只能为10位。 使用现有规则:len

<FormItem label="名称" {...formItemLayout}>
2     {getFieldDecorator('name', {
3         rules: [   
4             //输入值长度最少5位,最大10位               
5             {
6                min:3
7                message: "最小5位",    
8             },                    
9             {
10                 max:15
11                message: "最大10位",    
12             }
13 
14             //输入值长度需要为10位
15 //            {
16 //               len:10
17 //               message: "输入长度不足10位",    
18 //            }
19 
20         ],
21     })(
22         <Input placeholder="这里输入名称" allowClear />,
23     )}
24     </FormItem>

2. 判断输入值的有效性

方式一: 最简单使用getFieldDecorator中的rules验证

rules中定义校验规则,message为校验不通过时的提示文字

{getFieldDecorator('inputContent', {
2             rules: [{
3               required: true, 
4               message: '请输入内容!',
5             }],
6           })(
7             <Input />
8 )}
方式二: 通过validateStatus+help 同时来控制。

antd提供了validateStatus,help,hasFeedback 等属性,你可以不需要使用 Form.create 和 getFieldDecorator,自己定义校验的时机和内容。

validateStatus: 校验状态,可选 'success', 'warning', 'error', 'validating'。
hasFeedback:用于给输入框添加反馈图标。
help:设置校验文案。

注: 这种校验方法有一个不足之处,就是不使用getFieldDecorator的话没办法设置字段名,获取输入的值的时候不能用getFieldsValue和setFieldsValue等方法对表单进行赋值和取值。

例子:同时监测输入框内容是否为空和是否有效

设置了validateStatus,help,这个就不能使用方式三的validator方式校验了,会冲突,使得validator不生效。
且文案也只会显示help设置的提示文案("名称不能为空"),原先规则设置的message文案(message: "名称需要输入!")也不会生效。所以提示文案的变化也就只能用help来设置。

<FormItem {...formItemLayout}
2     label="名称"
3     validateStatus={this.state.showError ? "error" : (   
4         this.state.inputEmpty? "error":"")}
5     help={this.state.showError ? "输入名称不符合要求" : (
6         this.state.inputEmpty? "名称不能为空":"")}
7 >
8     {getFieldDecorator('name', {
9         initialValue: "",
10         rules: [
11             {
12                 required: true,
13                 message: "名称需要输入!",
14             },{
15                 validator: async (rule, value, callback) => {
16                     if(!value){
17                         this.setState({
18                             inputEmpty: true
19                         })
20                     }else{
21                         this.setState({
22                             inputEmpty: false
23                         })
24                     }                                                 
25                     
26                 }
27             }                                     
28         ],
29 
30     })(
31         <Input
32             placeholder="这里输入名称"
33             allowClear
34             onBlur={this.handleInputChange} />
35     )
36     }
37 </FormItem>

输入框的handleInputChange方法可自行实现,用来校验输入值是否符合要

方式三:使用getFieldDecorator的validator自定义校验

ant.design内部使用了async-validator,通过阅读async-validator的文档,了解到每个rule其实都是可以定制validator。validator是个函数,其中有三个参数很重要:rule,value和callback。

rule:这个是规则,可以不用
value:这个是要验证的值
callback:这个是回调函数,验证出错后可以把错误信息作为参数调用callback
举例:

<FormItem
 2     label="标签"
 3     labelCol={{ span: 6 }}
 4     wrapperCol={{ span: 14 }}>
 5     {getFieldDecorator('tags', {
 6         rules: [{
 7             required: true,
 8             type:'array',
 9             message:'必填',
10         },{
11             validator(rule, values, callback){
12                 if(values && values.length>0){
13                     values.map((value,i)=>{
14                         if(value.name.length > 16 ){
15                             callback(`第${i+1}个标签超过16个字符`);
16                         }else if(value.name.length == 0){    
17                             callback(`第${i+1}个标签不能为空`);
18                         }else{    
19                             callback();
20                         }
21                     });
22                 }else{
23                     callback();
24                 }
25             }
26         }],
27     })(
28         <MyTag />
29     )}
30 </FormItem>

还可以写成:

<FormItem
 2     label="标签"
 3     labelCol={{ span: 6 }}
 4     wrapperCol={{ span: 14 }}>
 5     {getFieldDecorator('tags', {
 6         rules: [{
 7             required: true,
 8             type:'array',
 9             message:'必填',
10         },{
11             validator: async (rule, value, callback) => {
12                   callback('Something wrong!');
13                 }
14             }
15         }],
16     })(
17         <MyTag />
18     )}
19 </FormItem>

还有种写法: 单独写一个handleValidator方法来处理

handleValidator = (rule, val, callback) => {
 2         if (!val) {
 3             callback();
 4         }
 5         let validateResult = ...;  // 自定义规则
 6         if (!validateResult) {
 7             callback('请输入正确的内容!');
 8         }
 9         callback();
10     }
11     
12     
13 {getFieldDecorator('validator', {
14     rules: [{
15         required: true,
16         message: '请输入内容'
17     }, {
18         validator: this.handleValidator
19     }]
20 })(
21     <input />
22 )}

注意:一个 Form.Item 建议只放一个被 getFieldDecorator 装饰过的 child,当有多个被装饰过的 child 时,help required validateStatus 无法自动生成。此时可用下面一种方法校验。

声明:该文章系转载,转载该文章的目的在于更广泛的传递信息

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,736评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,167评论 1 291
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,442评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,902评论 0 204
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,302评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,573评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,847评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,562评论 0 197
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,260评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,531评论 2 245
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,021评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,367评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,016评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,068评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,827评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,610评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,514评论 2 269