前言
在昨天刚结束的第一届 前端艺术家沙龙 上,NoForm 首次正式对外公布,鸣波大大发表非常精彩的演讲,后续现场有些童鞋对于这个话题也颇感兴趣,作为作者之一,也有义务把这个方案的前世今生讲一下。
为什么
有人说都8012年了,我们都把特斯拉送上月球了,还在做表单方案?
![5353902f6b6de2190bb3a7ce02c2bf69.png](https://i-blog.csdnimg.cn/blog_migrate/c5aec497b012044bd0a77573f040c1af.jpeg)
做 B类业务 的同学应该深有感触,我们日常需要面对大量操作类或者表单类的场景,因此只要是能从这些重复的CRUD解放出来的方案,就是最好的方案,
核心
NoForm想要呈现给开发者最重要的的点就是:自由
![8683f8e13d77a1deeae04d79e6789138.png](https://i-blog.csdnimg.cn/blog_migrate/b25193b287ad3b22cb7473443e786ff2.jpeg)
大部分的同学都自建了一些快速生成的方案,有配置类型的,动态生成类型的,在初期往往可以解决60-80%的问题,但需要去维护的时候,维护者就会非常痛苦 (定制化需求),因此当我们在说 提升效能 之前,更重要的是,用的爽(自由)。然后基于这点再做上层建筑才会更稳
快速开始
好了,吹B结束,以下是快速索引。这里主要讲设计,就像用户手册一样,希望读者看完也知道如何去编写代码了,当然文档也会附上:
- DEMO: 首先通过 DEMO 查看一些特性。
- 官网:https://alibaba.github.io/nopage
- GITHUB:https://github.com/alibaba/nopage
- Ant-Design最佳实践 https://alibaba.github.io/noform/#/docs?md=easy/best-practise-antd
主要设计
![aa0aa60ad711fb18c7fe149ca6a99fd3.png](https://i-blog.csdnimg.cn/blog_migrate/6d78b84a166330aa05d155638287d6f5.jpeg)
如图所示,我们会用 FomCore 这个纯逻辑的处理单元去描述表单,那么能够完整描述表单的话会有以下几个维度:
- values (最核心以及基本的维度)
- status (描述整体和个体状态,如 edit(编辑), preview(预览), disabled(禁用) )
- errors (描述目前表单有哪些字段校验不通过)
- props (描述目前表单各个字段当前属性,如prefix, suffix 等)
因此Form就变成完全受控的组件(即外部传入什么值,就显示什么值),这样控制FormCore就等于控制表单。
状态控制
如下图所示,状态控制的优势在于 同一份代码通过切换不同的状态 即可实现以下的需求。
![497119a33e1d4081febbe1797bdf2204.png](https://i-blog.csdnimg.cn/blog_migrate/b37322f891c121071bdf2d3cdde1aa32.jpeg)
上层拓展
基于这种基础设计,往上层拓展就会容易多了。
![36044ef7506b8224c54914da01d809e5.png](https://i-blog.csdnimg.cn/blog_migrate/a8ae76339edf2898e5335ec3f8757d76.jpeg)
做好自己的本分
NoForm的设计思路就是先做好底层模块,保证底层模块的 内聚性 和 鲁棒性,上层才会稳固。对于 表单领域来说,表单项(FormItem) 就是底层模块。
![b7f9c0d048ab6b71a31ea7c733e66413.png](https://i-blog.csdnimg.cn/blog_migrate/e2d9839771d5c02b3b9cb86620dbbfc3.jpeg)
![fe9a542dbb305dde2747e9331f67a161.png](https://i-blog.csdnimg.cn/blog_migrate/3ce6e5b7fb2cc43da1123a93b351ce9e.jpeg)
结合上面两图来看,Content 即实际的表单元素,如 Select/Input/Checkbox 等等,这样的话,上面提及的状态切换,也需要根据单个表单项的实现才得以完成。
![cee06f5e253a1f5e788a7353f464f7aa.png](https://i-blog.csdnimg.cn/blog_migrate/7e2ba779516f31cb22932b1261188770.jpeg)
根据以上设计,实际上,FormItem 就有维护自己的一份 values, errors, props, status 的itemCore , 而整体的值,实际上就是所有itemCore的总和。
![f5bcbd40838186b1a5ad4ba2d6e20b96.png](https://i-blog.csdnimg.cn/blog_migrate/3d365b266cc0347d05ee11540cebcdcf.jpeg)
看完前面的部分,可能会觉得NoForm整体的设计就很 “不负责任” ,把要做的事情都一层一层传递到下面的小弟身上,实际上这是尽量让专业的人做专业的事情,这样权责分明后维护的成本就会低很多。
控制机制
基于EventEmitter的设计是非常轻量和稳的设计,整体设计如图所示:
![2a91196777067deca177ea5d8e1dc324.png](https://i-blog.csdnimg.cn/blog_migrate/accc96e86979dc10382bbc5c81242917.jpeg)
联动
联动是表单领域一个非常头疼的问题,而 kk大佬 说NoForm的精髓是处理联动,说来惭愧,联动方面也是非常 “不负责任” 的, 以下代码就是NoForm实现联动的办法:让用户自己去处理...
- 显示联动
<FormItem label="username" name="username"><Input /></FormItem>
<If when={(values, formCore) => {
return values.username === 'bobby';
}}>
<div>anything you want to return....</div>
</If>
用户需要去实现 when 自己决定处理的逻辑,If 主要功能来处理 是否显示 的联动形式。
2. 逻辑联动
<
3. 触发联动的契机
除了用户自己输入外,也可以使用上面提及的 FormCore 去执行
core.setValues({ // 设置值
username: 'bobby',
age: 23
});
core.setGlobalStatus('preview'); // 设置全局状态
更多内容,请查看 联动 和 核心控制
以上提及的就是NoForm在表单领域内做的一些事情,当然还有 校验 等一些环节没有提及,读者都可以在链接或者上面的文档进行查阅。
表单组件化标准
NoForm做的另外比较大的一块是组件标准化,正如上面所示,NoForm是很 “不负责任” 的,这么做的目的是想把属于表单领域的逻辑无UI化。这样的话,我们可以快速接入社区优秀的组件库,诸如 Ant-Design 飞冰 等...
实际上标准的React受控组件,都可以无缝接入。因此接入自定义组件可以参考 组件接入的标准。而NoForm 自身集成了 Ant-Design 的适配层,因此可以无缝接入。
不是Ant-Design 也没有关系,适配层主要是做了两件事: 标准化 和 状态适配,详细的代码可以直接看 wrapper源码
TroubleShooting
以上就是NoForm设计的前世今生了,实际上在产出NoForm前内部还有很多实践,诸如mobx,基于 JSON-SCHEMA的联动和配置化渲染 等等,最终还是觉得底层需要做的比较薄,可控,强大但简洁,然后再基于这层往上拓展不至于伤到自己(很严肃不要笑...
![27dde8a4973a42930f32cbbc3ebcc2ae.png](https://i-blog.csdnimg.cn/blog_migrate/73bfc3eec0e2b4a49eb395165e60210c.jpeg)
Roadmap
按照惯例还是要澄清一下这不是KPI项目,然后NoForm只是一个起点,我们希望它足够稳定和可信赖,目前放出的版本是0.x,还会迭代约2个月左右升级至1.x,后续会有一系列的升级步骤。
1.x 和 0.x 除了适配层都是兼容性升级,2.x 由于会接入vue 即将会是非兼容性升级
- 0.x 维护至 11月
- 1.x 整体升级至react@16 , 第三方适配层Ant-Design 独立一个库出来, 针对Ice 和 zent独立设计适配层库
- 2.x 整体核心逻辑独立,vue版本产出(欢迎vue大佬加入我们一起搞起 ...
结语
不知不觉写了好长,这是团队向外暴露的第一个产品,后续会有更多的产品在路上,昨天会后有一些小伙伴表示非常想用,在这里也恳请各位尝试的小伙伴无论最终是否会用在自己的产品线上,有任何的问题都可以在Github上留下你的反馈,哪怕你不喜欢,也恳请告知离开的理由,因为我们是非常想把这款产品做好的,感谢...
为了更好更快的反馈使用者的问题,欢迎使用钉钉和我们联系。(比较尴尬,钉钉会自动转二维图,还是直接搜群号比较快)
钉钉群号: 23134927