表单常用的校验

  • required:是否必选
  • enum:枚举类型
  • len:字段长度
  • max:最大长度
  • min:最小长度
  • transform 转换

async-validator

https://github.com/yiminghe/async-validator#type
Indicates the type of validator to use. Recognised type values are:

  • string: Must be of type string. This is the default type.
  • number: Must be of type number.
  • boolean: Must be of type boolean.
  • method: Must be of type function.
  • regexp: Must be an instance of RegExp or a string that does not generate an exception when creating a new RegExp.
  • integer: Must be of type number and an integer.
  • float: Must be of type number and a floating point number.
  • array: Must be an array as determined by Array.isArray.
  • object: Must be of type object and not Array.isArray.
  • enum: Value must exist in the enum.
  • date: Value must be valid as determined by Date
  • url: Must be of type url.
  • hex: Must be of type hex.
  • email: Must be of type email.
  • any: Can be any type.

常用的表单校验规则 rules

参数 说明 类型
len 字段长度 Number
max 最大长度 Number
min 最小长度 Number
message 校验文案 String
pattern 正则表达式校验 Regexp
required 是否必选 Boolean
type 内置校验类型 String
validator 自定义校验函数 Function
whitespace 必须时,空格是否会被视为错误 Boolean
  1. import Schema from 'async-validator';
  2. const rules = [
  3. { required: true, message: '请输入用户名' }, // type: 'string' 默认
  4. {
  5. type: 'url',
  6. message: '<mark>请输入 URL</mark>', // jsx格式
  7. },
  8. {
  9. type: 'email',
  10. pattern: Schema.pattern.email, // 自定义正则表达式
  11. message: () => this.$t('email is required'), // 多语言
  12. },
  13. { type: 'hex', message: '请输入用户名' },
  14. { type: 'date', message: '请输入用户名' },
  15. { type: 'boolean', message: '请输入用户名' },
  16. { type: 'method', message: '请输入用户名' },
  17. { type: 'enum', enum: ['admin', 'user', 'guest'], message: '请输入用户名' },
  18. // 指定范围
  19. { min: 6, max: 20, message: '用户名6-20个字符' },
  20. // 字段包含空格,校验不通过
  21. { whitespace: true, message: '不能输入空格' },
  22. // 指定长度
  23. { type: 'any', len: 20, message: '请输入用户名' },
  24. ]
  25. // number
  26. const numberRules = [
  27. { required: true, type: 'number', message: '请输入数字' },
  28. { type: 'integer', message: '请输入数字' },
  29. { type: 'float', message: '请输入用户名' },
  30. {
  31. required: true,
  32. whitespace: true,
  33. type: 'number',
  34. transform(value) {
  35. // 将字符串转换成数字
  36. if(value) return Number(value)
  37. }
  38. }
  39. ]
  40. // array
  41. const arrayRules = [
  42. {
  43. required: true,
  44. type: 'array',
  45. len: 3,
  46. fields: {
  47. 0: { type: 'string', required: true, message: '请输入用户名' },
  48. 1: { type: 'string', required: true, message: '请输入用户名' },
  49. 2: { type: 'string', required: true, message: '请输入用户名' },
  50. },
  51. },
  52. {
  53. required: true,
  54. type: 'array',
  55. defaultField: { type: 'url' },
  56. },
  57. ]
  58. // object
  59. const objectRules = [
  60. {
  61. required: true,
  62. type: 'object',
  63. fields: {
  64. street: { type: 'string', required: true, message: '请输入街道' },
  65. city: { type: 'string', required: true, message: '请输入城市' },
  66. zip: { type: 'string', required: true, len: 8, message: '无效的 zip压缩文件' },
  67. },
  68. options: { first: true },
  69. },
  70. ]
  71. // validator 自定义校验
  72. const customRules = [
  73. {
  74. validator(rule, value, callback) {
  75. if (value === 'test') {
  76. return Promise.resolve();
  77. }
  78. return Promise.reject('两次输入的密码不一致');
  79. },
  80. },
  81. {
  82. validator(rule, value, callback) {
  83. return new Error(`${value} is not equal to 'test'`);
  84. },
  85. },
  86. ]

formRef hasFeedback

  • validateStatus: 校验状态,可选 ‘success’, ‘warning’, ‘error’, ‘validating’
  • hasFeedback:用于给输入框添加反馈图标
  • help:设置校验文案 ```tsx import React from ‘react’; import { Button, Form, Input, Select } from ‘antd’; import type { FormInstance } from ‘antd/es/form’;

function App() { const formRef = React.useRef(null);

const onReset = () => { formRef.current?.resetFields(); };

const onFill = () => { formRef.current?.setFieldsValue({ note: ‘Hello world!’, price: 200 }); };

  1. return(
  2. <Form
  3. ref={formRef}
  4. labelCol={{ span: 8 }}
  5. wrapperCol={{ span: 16 }}
  6. initialValues={{ remember: true }}
  7. onFinish={onFinish}
  8. onFinishFailed={onFinishFailed}
  9. autoComplete="off" // 关闭自动填充
  10. >
  11. <Form.Item
  12. name="price"
  13. label="价格"
  14. hasFeedback
  15. validateStatus="success"
  16. labelWrap
  17. wrapperCol={{ flex: 1 }}
  18. >
  19. <InputNumber/>
  20. </Form.Item>
  21. </Form>

) }

  1. <a name="RIigF"></a>
  2. ### useForm
  3. ```tsx
  4. import { Button, Form, Input, Select } from 'antd';
  5. function App() {
  6. const [form] = Form.useForm();
  7. // const [form] = Form.useForm<{ name: string; price: number }>();
  8. const priceValue = Form.useWatch('price', form);
  9. return(
  10. <Form
  11. form={form}
  12. labelCol={{ span: 8 }}
  13. wrapperCol={{ span: 16 }}
  14. initialValues={{ remember: true }}
  15. onFinish={onFinish}
  16. onFinishFailed={onFinishFailed}
  17. >
  18. <Form.Item
  19. name="price"
  20. label="价格"
  21. rules={[
  22. { required: true, type: 'integer', message: '请输入数字' },
  23. ]}
  24. >
  25. <InputNumber/>
  26. </Form.Item>
  27. <Form.Item wrapperCol={{ offset: 8, span: 16 }}>
  28. <Button type="primary" htmlType="submit">
  29. Submit
  30. </Button>
  31. </Form.Item>
  32. </Form>
  33. )
  34. }

pattern正则验证

手机号码验证

  1. const rules = [
  2. {
  3. required: true,
  4. pattern: /^1[3-9]\d{9}$/,
  5. max: 11,
  6. message: '手机号码错误',
  7. },
  8. validateTrigger: 'onBlur' // onFocus
  9. ]
  10. const patternRules = [
  11. { type: 'regexp', message: '请输入数字' },
  12. {
  13. pattern: new RegExp(/^[0-9a-zA-Z_]{1,}$/, 'g'),
  14. message: '请输入数字,字母,下划线',
  15. },
  16. {
  17. pattern: /^[0-9a-zA-Z]{6,16}$/,
  18. message: '密码长度为6-16位,只能包含数字和英文',
  19. },
  20. {
  21. pattern: /(^\d{15}$)|(^\d{17}([0-9]|X)$)/g,
  22. message: '身份证号码错误',
  23. },
  24. {
  25. pattern: /^1[3-9]\d{9}$/,
  26. max: 11,
  27. message: '手机号码错误',
  28. },
  29. {
  30. type: 'string',
  31. pattern: /^[0-9]+$/,
  32. message: '只能输入数字',
  33. },
  34. ]

validator 自定义验证

https://ant.design/components/form-cn#rule
antd form 4x 验证返回 Promise,validator(rule, value) => Promise

  1. const passwordRules = [
  2. { required: true, message: '请输入密码' },
  3. // form
  4. ({ getFieldValue }) => ({
  5. validator(_, value) {
  6. if (!value || getFieldValue('password') === value) {
  7. return Promise.resolve();
  8. }
  9. return Promise.reject(new Error('两次密码输入不一致!'));
  10. },
  11. }),
  12. ]
  13. const agreementRules = [
  14. {
  15. validator: (rule, value) => {
  16. if (value) return Promise.resolve();
  17. return Promise.reject(new Error('请阅读并勾选协议'))
  18. }
  19. }
  20. ]
  21. // validator 自定义校验
  22. const customRules = [
  23. {
  24. validator(rule, value) {
  25. if (value === 'test') {
  26. return Promise.resolve();
  27. }
  28. return Promise.reject('两次输入的密码不一致');
  29. },
  30. },
  31. {
  32. validator(rule, value) {
  33. return new Error(`${value} is not equal to 'test'`);
  34. },
  35. },
  36. ]

antd form 3x

https://github.com/ant-design/ant-design/issues/5155
validator(rule 规则,value 输入的值,callback 回调函数)

必须要调用 callback,不管你 callback返回不返回提示的内容,都要写callback这个函数。

  • 不返回内容写个空的callback()
  • 如果不写的话,在form表单中 用 props.form.validateFields校验是进不来 if(!err) 这个判断中的
    1. form.validateFields((err, values)=>{
    2. // 如果在请求成功后不写 callback() 那么是进不来这个判断中的
    3. if(!err){}
    4. })

在getFieldDecorator包装的控件,表单控件会自动的添加value。可能这样说是不正确的,

  • 因为在getFieldDecorator之后,需要使用initialValue来动态绑定这个input的value值
  • rules这里面可以定义这个表单的触发时间,长度,必填项,以及提示语等等东西 ```javascript function checkValue(rule, value, callback) {
    if(value.length > 0){ if (rule.pattern.test( value )) {
    1. callback()
    } else {
    1. callback('请输入正确的手机号码');
    } } callback(‘手机号码不能为空’) }

// validator 自定义校验 const rules =[ { required: true, message: ‘请再次输入密码’ }, { validator: passwordValidator } ]

// 密码验证 export function passwordValidator(rule, value, callback) { const { getFieldValue } = form; if (value && value !== getFieldValue(‘password’)) { callback(‘两次输入不一致!’) } // 必须总是返回一个 callback,否则 validateFields 无法响应 callback(); } ```