背景
一直做的erp类的项目,发现很多时候表单都有很多类似的交互,包括列表页的页头搜索项,都有搜索,重置,审批类表单都有审批人,附件等,于是就打算针对于表单做一次封装,使用json数据去渲染,这样每次渲染一个表单页就可以通过传递一个json去生成,内置一些交互逻辑
但其实是否有必要这么封装也是待商榷的,在做的过程中其实我也一直在自我怀疑,优点是对于一些常规的表单,一个json就能直接渲染,但是对于一些特殊的操作,虽然我提供了插槽,也提供了很多支持的方法暴露出来,但是其实并没有那么直观,也就是说如果不熟悉这个项目的人,一看到这种封装的表单会一脸懵逼,而且初始开发的时候,往往项目组的人必须去看我的api文档,增加了开发的成本。初始的时候只是想做一下布局的封装,然后组件还是以插槽的形式去写,但是感觉这种封装又没有一点封装的意义。做着做着总会问自己一个问题,是否过渡封装,是否真的有在降低开发成本,总之见仁见智吧,有更好的方法请留言
思路
使用循环渲染组件,是插槽的就使用具名插槽渲染,不是的则根据类型去渲染固定的内置组件
多次实现的一步步升级
组件兼容
使用listener 去做组件兼容。很多时候我们都有一个UI组件库,开始的时候完全不考虑后续扩展兼容,就直接按当前业务去弄,后续加一个变化就又要去改代码,后面针对这些组件做兼容处理,反正原生的组件有啥属性就通过配置传进来,至于监听方法,就用另一个对象传进来,然后发现一个有意思的现象,就比如我使用element的select,在组件定义了@change方法,同时我v-on一个对象 对象中有一个change属性绑定一个方法,会先执行@change的方法,再执行v-on里的change方法,并不是覆盖
组件联动
其实我没有去实现组件之间的联动,而是把联动的逻辑交由调用者去实现。我在表单子组件生成后,会去收集每一个组件的实例抛出去给调用者,调用者可以通过对应的key值去拿到当前的一个组件实例,并且提供了change方法,也就是每一项发生变化都会触发change方法,而change方法会带出相应的key值,你可以根据当前的key值去判断是否做级联操作,例如 A项发生变化会导致B项的下拉值发生变化,那可以再调用的change时间中监听key值是否为A,如果为A的话 那么B组件的实例去修改某些配置项或者修改值
这样的好处是灵活,这样我也不用考虑A影响BCD反正有什么影响调用者自己处理
组件的扩展
关于要写多少组件的问题,其实是业务决定的,后续要怎么去增加内置组件是一个问题,开始我是写在一个文件中的,然后用v-if去控制显隐,但发现一个问题,这样下去万一来个20个组件那我的这个文件就会丑陋无比,而且针对每个组件的特殊处理方法会使得代码里和屎一样存在了各种各样的if判断
<components/>解决了我这个问题,动态引入就好了,至于怎么引入组件,那就使用webpack的require.context去自动引入,这样就相当于每增加一个组件文件,内置组件就增加一个。示例
同时,每个组件其实都有很多相似的方法,可以抽离出来,引用hook的一个概念,这样扩展一个组件就只需要针对自己的特殊性做一些方法的覆盖,普通的组件就引入hook中封装的方法做处理就好了示例
后话
其实写这个东西到后面因为写的多了,代码一点一点反而更加的精简,但是使用成本上目前还没有定性到底有没有效率上的提升,总之探讨吧,有不正之处请指正