--- order: 2 toc: content mobile: false group: title: 高级用法 order: 1 --- # 表单校验 - 通过内置校验字段配置,实现简单校验逻辑 - 通过 rules 配置,实现复杂校验逻辑 - 通过 validateMessages 实现校验提示模版定制 ### 一、内置校验 - required:必填 - max:最大长度 | 最大值 - min:最小长度 | 最小值 - format:url | email | image | color ```jsx import React from 'react'; import FormRender, { useForm } from 'form-render'; const schema = { type: 'object', displayType: 'row', properties: { input1: { title: '必填', type: 'string', required: true, }, input2: { title: '数字最大值', type: 'number', max: 2, required: true }, input3: { title: '数字最小值', type: 'number', min: 10, required: true, }, input4: { title: '字符最大长度', type: 'string', max: 2, required: true, }, input5: { title: '字符最小长度', type: 'string', min: 10, required: true, }, input6: { title: 'url 校验', type: 'string', required: true, format: 'url', }, input7: { title: 'email 校验', type: 'string', required: true, format: 'email', }, input8: { title: '图片格式校验', type: 'string', required: true, format: 'image', } } }; export default () => { const form = useForm(); return ( ) }; ``` ### 二、Rules 校验 - 全面拥抱 Antd Form Rules - 自定义校验 validator:做了一点小小的改变,validator 直接返回布尔值。 ```jsx import React from 'react'; import FormRender, { useForm } from 'form-render'; const schema = { type: 'object', displayType: 'row', properties: { input1: { title: '正则表达式', type: 'string', required: true, rules: [ { pattern: '^[\u4E00-\u9FA5]+$', message: '请输入中文!' } ] }, input2: { title: '自定义校验', type: 'string', rules: [ { validator: (_, value) => { const pattern = '^[\u4E00-\u9FA5]+$'; const result = new RegExp(pattern).test(value); return result; // 或者是返回一个对象,用于动态设置 message 内容 // return { // status: result, // message: '请输入中文!', // } }, message: '请输入中文!' } ] } } }; export default () => { const form = useForm(); return ( ) }; ``` ### 三、子表单校验 自定义组件是一个子表单时,表单提交是无法触发子表单进行校验的,所以这种类型的子组件需要单独处理 ```js import { useImperativeHandle } from 'react'; const ChildForm = (props) => { // 内部校验方法,异步校验请用 async、await 语法 const validator = async () => { return true; // 返回 boolean 值,true 表示内部校验通过 // 如果需在外部显示子表单错误信息可以使用对象形式返回 // retrun { status: boolean, message: string }; }; useImperativeHandle(props.addons.fieldRef, () => { // 将校验方法暴露出去,方便外部表单提交时,触发校验 return { validator }; }); return ( ...// 表单渲染代码 ); } export default ChildForm; ``` ### 四、定制校验模版 - 全面拥抱 Antd Form Rules - validateMessages:通过配置 validateMessages 定制校验模版,可以按需定制,定制模版会和默认校验模版进行合并处理 ```jsx import React from 'react'; import FormRender, { useForm } from 'form-render'; const schema = { type: 'object', displayType: 'row', properties: { input1: { title: '地址(必填)', type: 'string', required: true, } } }; export default () => { const form = useForm(); const validateMessages = { required: '${label} 不能为空', }; return ( ) }; ``` ### 五、默认模版内容 - 中文模版 ```Js const typeTemplate = '${label}的类型不是${label}'; const validateMessagesCN = { default: '${label}未通过校验', required: '${label}必填', whitespace: '${label}不能为空', date: { format: '${label}的格式错误', parse: '${label}无法被解析', invalid: '${label}数据不合法', }, types: { string: typeTemplate, method: typeTemplate, array: typeTemplate, object: typeTemplate, number: typeTemplate, date: typeTemplate, boolean: typeTemplate, integer: typeTemplate, float: typeTemplate, regexp: typeTemplate, email: typeTemplate, url: typeTemplate, hex: typeTemplate, }, string: { len: '${label}长度不是${len}', min: '${label}长度不能小于${min}', max: '${label}长度不能大于${max}', range: '${label}长度需在${min}与${max}之间', }, number: { len: '${label}不等于${len}', min: '${label}不能小于${min}', max: '${label}不能大于${max}', range: '${label}需在${min}与${max}之间', }, array: { len: '${label}长度不是${len}', min: '${label}长度不能小于${min}', max: '${label}长度不能大于${max}', range: '${label}长度需在${min}与${max}之间', }, pattern: { mismatch: '${label}未通过正则判断${pattern}', }, }; ``` - 英文模版 ```Js const typeTemplate = "'${label}' is not a valid ${type}"; const validateMessages = { default: "Validation error on field '${label}'", required: "'${label}' is required", enum: "'${label}' must be one of [${enum}]", whitespace: "'${label}' cannot be empty", date: { format: "'${label}' is invalid for format date", parse: "'${label}' could not be parsed as date", invalid: "'${label}' is invalid date", }, types: { string: typeTemplate, method: typeTemplate, array: typeTemplate, object: typeTemplate, number: typeTemplate, date: typeTemplate, boolean: typeTemplate, integer: typeTemplate, float: typeTemplate, regexp: typeTemplate, email: typeTemplate, url: typeTemplate, hex: typeTemplate, }, string: { len: "'${label}' must be exactly ${len} characters", min: "'${label}' must be at least ${min} characters", max: "'${label}' cannot be longer than ${max} characters", range: "'${label}' must be between ${min} and ${max} characters", }, number: { len: "'${label}' must equal ${len}", min: "'${label}' cannot be less than ${min}", max: "'${label}' cannot be greater than ${max}", range: "'${label}' must be between ${min} and ${max}", }, array: { len: "'${label}' must be exactly ${len} in length", min: "'${label}' cannot be less than ${min} in length", max: "'${label}' cannot be greater than ${max} in length", range: "'${label}' must be between ${min} and ${max} in length", }, pattern: { mismatch: "'${label}' does not match pattern ${pattern}", }, }; ```