React Form组件的实现封装杂谈(3)
当需要获取表单字段值的时候,只需要遍历fields数组,再调用Field实例的相应方法就可以:
/** * createForm高阶函数 */ const createForm = (config = {}) => { ... return WrappedForm => { return class Form extends Component { getFormValues = () => { return this.fields.reduce((values, field) => { const name = field.getName(); const fieldValue = field.getValue(); values[name] = fieldValue; return values; }, {}); }; } } } /** * Field组件 */ class Field extends Component { getValue = () => { return this.state._value; }; }
表单验证&错误提示
表单验证是一个重头戏,只有验证通过了才能提交表单。验证的时机也有多种,如字段变更时、鼠标移出时和表单提交时。ZentForm提供了一些常用的验证规则,如非空验证,长度验证,邮箱地址验证等。当然还能自定义一些更复杂的验证方式。自定义验证方法可以通过两种方式传入ZentForm,一种是通过给createForm传参:
createForm({ formValidations: { rule1(values, value){ }, rule2(values, value){ }, } })(FormComp);
另一种方式是给Field组件传属性:
<Field validations={{ rule1(values, value){ }, rule2(values, value){ }, }} validationErrors={{ rule1: 'error1', rule2: 'error2' }} />
使用createForm传参的方式,验证规则是共享的,而Field的属性传参是字段专用的。validationErrors指定校验失败后的提示信息。这里的错误信息会显示在前面getControlGroup所定义HTML中{showError && (<p className="zent-form__error-desc">{props.error}</p>)}
ZentForm的核心验证逻辑是createForm的runRules方法,
runRules = (value, currentValues, validations = {}) => { const results = { errors: [], failed: [], }; function updateResults(validation, validationMethod) { // validation方法可以直接返回错误信息,否则需要返回布尔值表明校验是否成功 if (typeof validation === 'string') { results.errors.push(validation); results.failed.push(validationMethod); } else if (!validation) { results.failed.push(validationMethod); } } Object.keys(validations).forEach(validationMethod => { ... // 使用自定义校验方法或内置校验方法(可以按需添加) if (typeof validations[validationMethod] === 'function') { const validation = validations[validationMethod]( currentValues, value ); updateResults(validation, validationMethod); } else { const validation = validationRules[validationMethod]( currentValues, value, validations[validationMethod] ); } }); return results; };
内容版权声明:除非注明,否则皆为本站原创文章。