,我们从官网摘下来一段Form代码,可以很清晰的看出一个简单的表单,主要是为了统一收集和校验组件的值。,那么它是如何做到统一收集和校验呢?原理很简单,只需要通过监听表单组件的onChange事件,获取表单项的 value,根据定义的校验规则对 value 进行检验,生成检验状态和检验信息,再通过setState驱动视图更新,展示组件的值以及校验信息即可。
,要实现上面的方案需要解决这几个问题:
,接下来我们就带着这几个问题,一起来一步步实现
,,1659421573127.jpg
,本项目采用ts来搭建,所以我们先定义数据类型;,因为我们的表单一定是各种各样不同的数据项,比如input、checkbox、radio等等,如果这些组件每一个都要自己管理自己的值,那组件的数据管理太杂乱了,我们做这个也就没什么必要性了。那要如何统一管理呢?其实就是我们自己定义一个数据仓库,在最顶层将定义的仓库操作和数据提供给下层。这样我们就可以在每层都可以操作数据仓库了。数据仓库的定义,说白了就是一些读和取的操作,将所有的操作都定义在一个文件,代码如下:,当然,数据仓库不能就这么放着,我们需要把里面的内容暴露出去。这里用ref来保存,来确保组件初次渲染和更新阶段用的都是同一个数据仓库实例;,我们先来定义一下表单的结构,如下代码所示:,定义了数据仓库,就要想办法在每一层都要拥有消费它的能力,所以这里在最顶层用context来跨层级数据传递。通过顶层的form将数据仓库向下传递,代码如下:,子组件来做存与取的操作。这里有个疑问,为什么不直接在input、radio这些组件上直接加入存取操作,非得在外面包一层Field(在正式的antd中是Form.Item)呢?这是因为需要在它基础的能力上扩展一些能力。,这样我们就完成了数据收集以及保存的功能了。
,很简单吧,我们来试一下onFinish操作!图片
,接下来我们继续完善其他的功能。
,我们来修改一下Form的代码,加入一条设置默认值:,来看一眼页面,发现我们设置的默认值并没有展示在表单中,但是我们提交的时候还是可以打印出数据的,证明我们的数据是已经存入到store中了,只是没有渲染到组件中,接下来我们需要做的工作就是根据store变化完成组件表单的响应功能。,,我们在useForm中加入订阅和取消订阅功能代码;,forceUpdate的作用是进行子组件更新;,当然光是注册是不够的,我们需要在设置值的时候完成响应;,我们来看一下效果,发现组件已经将值更新啦;,,到现在为止,我们发现提交表单还没有校验功能。表单校验通过,则执行onFinish。表单校验的依据就是Field的rules,表单校验通过,则执行onFinish,失败则执行onFinishFailed。接下来我们来实现一个简单的校验。
,修改代码结构,添加validateField方法进行表单校验。注意:此版本校验只添加了required校验,后续小伙伴们可以根据自己的需求继续完善哦!
,我们只需要在form提交的时候判断一下就可以啦;,密码为空时的实现效果;,,账号密码都不为空时的实现效果;,,做到这里,我们已经基本实现了一个Antd Form表单了,但是细节功能还需要慢慢去完善,感兴趣的小伙伴们可以接着继续向下做!,其实我们在看Antd Form源码的时候会发现它是基于rc-field-form来写的。所以想继续向下写的小伙伴可以下载rc-field-form源码,边学习边写,这样就可以事半功倍了,攻克源码!,,本篇文章代码地址:https://github.com/linhexs/vite-react-ts-form
© 版权声明
文章版权归作者所有,未经允许请勿转载。