本文作者:IMWeb 结一
未经同意,禁止转载
一直以来,表单对于前端来说都是一个不得不面对的坑。而对于设计一个表单组件来说,主要需要考虑以下三点:
各个元素如何排版布局
管理各个元素的值
表单验证(即时校验及提交的全部校验)
目前已经有了一批优秀的 form 表单解决方案,但是要解决上述的三大问题,都比较费劲,于是搞了个
react-form-next ,力求将整个表单组件所涉及到的问题都简化点。
简单演示
以下图的一个简单的表单为例:
布局采用传统的一行一个表单项,验证条件如下:
用户名默认为ycxu,不允许为空
邮箱不能为空,邮箱格式验证
年龄不能为空,只能是数字,且范围为18-30之间的数字。除此以外,onChange 的时候要立即校验。
提交之前校验全部
体验地址为: React form demo。核心组件代码如下:
下面简单解释下各个组件的用途:
FormReducer 组件,使用最新的 react hook api 自动管理整个表单的数据。并且创建了一个 context。
FormReducerItemContext 组件,表示自动注入了 context(value, checkMsg, onChange) 的表单项组件。所以组件中没有value,checkMsg(校验信息),onChange 这三个属性。其中年龄中 changeAutoCheck 属性表示值改变的时候立即校验。
FormItem 组件,表示表单项组件,主要解决了各个元素如何排版布局的问题。
FormReducerSubmitContext 表示注入了提交之前先全部校验的逻辑。
下面我们一一分析具体的实现。
各个元素如何排版布局
首先,整个表单可以分为多个表单项。而一个表单项从结构上可能会涉及到 6 个部分:label、前缀、表单元素(或自定义的表单元素)、后缀、说明文字,校验态。大概如下图:
大体 HTML 结构可以设计如下:
div.f-item
label.f-label // 如果需要标注required,子元素还要加个required判断
div.f-field
div.f-element-wrap // 如果没有前后缀,可以不需要该层
span.f-prefix // 前缀
input.f-element // 输入框等表单元素
span.f-suffix // 后缀
p.f-description // 描述说明
div.f-msg // 检验信息
当然还有一些非常简单的情况,不需要进行验证,而提示信息也可以使用 placeholder 来搞定,所以是不需要这么多层结构的,于是结构可以简化如下:
div.f-item
label.f-label // 如果需要标注requiredÿ