“那要怎么改?”,“那得改到什么时候?”,“什么时候才能支持这些功能?”。
再一次听到了这样的话,我沉默了。到底要怎样改,这也是我所思考的,最近一直忙于其他,已经有一段时间没有处理 issue 了,趁着调休,我也要好好思考下。
半年前,接触了 el-form-renderer ,瞬间感觉减轻了大部分表单编写的工作,一个简单的JSON配置,立刻展现出一个功能完好的表单页面。然而,随着使用的频率增加,却慢慢开始暴露各种不足,该组件的作者也不再单独对该组件进行维护了。由于项目表单场景的需要,我们 fork 了一个版本,但后来发现我们更想要的是一套属于我们自己的表单渲染规则,于是在我们的 Github 组织下建立了属于我们的代码仓库 @femessage/el-form-renderer (以下都称为 el-form-renderer ),并开始了我们自己维护之路。
3W
el-form-renderer 是什么?为什么?怎么样?通过3W分析来看看我们做了什么。
WHAT?
基于 element-ui 封装的 表单渲染器 ,但不仅仅是 element-ui ,甚至不仅仅是表单。
WHY?
这里的为什么有两层,第一层是为什么需要表单渲染器?第二次是什么是 el-form-renderer ?
借用《NoForm - 一个更好的表单解决方案》中的一句话:
做 B类业务 的同学应该深有感触,我们日常需要面对大量操作类或者表单类的场景,因此只要是能从这些重复的CRUD解放出来的方案,就是最好的方案
我们的目的也很简单,让天下没有难做的表单。
至于为什么是 el-form-renderer ,理由很简单,我们正在让没有难做的表单变成现实,至少在目前数十个项目中,解决了70%以上的表单方面的需求。
HOW?
如上文所说,如下图所见:
一个好的表单需要解决的问题:
•表单的取值、赋值、校验
•表单联动
•自定义表单项
•表单项的事件、属性、slot
•对用户足够友好
所谓”下层基础决定上层建筑“,我们没有执着于从0开始,而是“让专业的人做专业的事”。基础组件, element-ui 足够专业,也正因为它的专业性,才让 el-form-renderer 最初的版本有了用武之地。然而目前远远不够的是,我们没有很好的处理表单联动和表单项的事件、slot的问题,这也正是我所要思考的地方。
基础用法
先来看看目前我们的实现(更多请参考 文档 )
<template> <el-form-renderer label-width="100px" :content="content" /> </template> <script> import UploadToAli from '@femessage/upload-to-ali' export default { data () { return { content: [ { $id: 'avatar', label: '头像', component: UploadToAli }, { $id: 'username', label: '用户名', $type: 'input', $el: { placeholder: '请输入用户名' } } ] } } } </script>
效果如下:
没有复杂的逻辑,只需进行简单配置 JSON 的方式就可实现常用表单功能
解决方案
因为不是从0开始,所以一开始作者的设计只服务于 element-ui 已有的组件。
之前的方案解决了什么
• 表单的取值 getValue ,赋值 updateValue
• 完整继承了 element 的 form 表单属性,包括校验
• 表单联动 $enableWhen
大部分简单的场景已经覆盖,但是局限于 element-ui 组件,没有处理好动态组件选项(如下拉选项)的问题,无法批量赋值,必须手动去空格...
现在的方案优化了什么
• 支持自定义组件,摆脱对 element-ui 的完全依赖(仍然依赖它的 el-form , el-form-item )
• 通过 setOptions 方法,动态的处理组件选项问题
• 添加批量更新数据方法 updateForm ,并添加 trim 来处理值
• 为了方便在其他组件中的集成和设置/获取值的需求,还添加了 inputFormat 、 outputFormat ( issue )
它本已完成了一个华丽的蜕变,甚至成为了我司组件的桥梁地位,然而,面对千奇百怪的需求,它确实还不够。
存在的问题
目前的7个 issue ,大致可以分为一下几类:
•表单联动
•自定义slot位置
•自定义事件
•其他优化
需求告诉我们,它还有很大的进步空间。
思考
回到开始的那些话,面对存在的问题,我们要怎么处理好它。