表单的字段一般包括两部分,一部分是标题,另一部分是内容。ZentForm通过getControlGroup这一高阶函数对结构和样式做了一些封装,它的入参是要显示的组件:
export default Control => { render() { return ( <div className={groupClassName}> <label className="zent-form__control-label"> {required ? <em className="zent-form__required">*</em> : null} {label} </label> <div className="zent-form__controls"> <Control {...props} {...controlRef} /> {showError && ( <p className="zent-form__error-desc">{props.error}</p> )} {notice && <p className="zent-form__notice-desc">{notice}</p>} {helpDesc && <p className="zent-form__help-desc">{helpDesc}</p>} </div> </div> ); } }
这里用到的label和error等信息,是通过Field组件传入的:
<Field label="预约门店:" name="dept" component={CustomizedComp} validations={{ required: true, }} validationErrors={{ required: '预约门店不能为空', }} required />
这里的CustomizedComp是通过getControlGroup封装后返回的组件。
字段与表单之间的交互是一个需要考虑的问题,表单需要知道它包含的字段值,需要在适当的时机对字段进行校验。ZentForm的实现方式是在Form的高阶组件内维护一个字段数组,数组内容是Field的实例。后续通过操作这些实例的方法来达到取值和校验的目的。
ZentForm的使用方式如下:
class FieldForm extends React.Component { render() { return ( <Form> <Field name="name" component={CustomizedComp} </Form> ) } } export default createForm()(FieldForm);
其中Form和Field是组件库提供的组件,CustomizedComp是自定义的组件,createForm是组件库提供的高阶函数。在createForm返回的组件中,维护了一个fields的数组,同时提供了attachToForm和detachFromForm两个方法,来操作这个数组。这两个方法保存在context对象当中,Field就能在加载和卸载的时候调用了。简化后的代码如下:
/** * createForm高阶函数 */ const createForm = (config = {}) => { ... return WrappedForm => { return class Form extends Component { constructor(props) { super(props); this.fields = []; } getChildContext() { return { zentForm: { attachToForm: this.attachToForm, detachFromForm: this.detachFromForm, } } } attachToForm = field => { if (this.fields.indexOf(field) < 0) { this.fields.push(field); } }; detachFromForm = field => { const fieldPos = this.fields.indexOf(field); if (fieldPos >= 0) { this.fields.splice(fieldPos, 1); } }; render() { return createElement(WrappedForm, {...}); } } } } /** * Field组件 */ class Field extends Component { componentWillMount() { this.context.zentForm.attachToForm(this); } componentWillUnmount() { this.context.zentForm.detachFromForm(this); } render() { const { component } = this.props; return createElement(component, {...}); } }
内容版权声明:除非注明,否则皆为本站原创文章。