Vue3 项目中,如何设计一个表单配置生成器?

科技   2024-12-07 10:36   广东  

Vue3项目中,如何设计一个表单配置生成器?

前言

大家好,我是林三心,用最通俗易懂的话讲最难的知识点是我的座右铭,基础是进阶的前提是我的初心~

背景

最近公司新开了一个 Vue3 的项目,并且让我做了组长,并且交待说可以开发一些基础组件,提高整个团队的开发效率,于是我首先想到的是封装一个表单配置组件,只需要传入配置,就可以生成表单,减少组员的开发负担~

源码+示例:https://github.com/sanxin-lin/all-example/tree/main/form-factory

组员们说以前开发一个表单需要:模板写组件,配置属性,配置规则,获取实例,逻辑分散等等操作,并且每个人都不统一,所以我才决定开发一个统一的表单配置组件~当然这只是一个初步版本,后面会拓展其他新功能的!!!

这个表单配置组件已经在项目中使用了,成员们都觉得大大提高开发效率,因为使用起来真的很简单~初步调研,组员们说效率至少提升了30%!!!!!

具体使用方法如下,其实重要部分就四个部分:

  • 1、表单选项:options
  • 2、表单配置:config
  • 3、表单状态:formState
  • 4、表单实例:formRef

定义完后,传入 FormFactory 组件,便可以生成表单

思考

其实代码不重要,我们要想想,实现这个东西需要注意哪些点,思路是怎么样的,想要看完整源码和示例的,可以看这里

源码+示例:https://github.com/sanxin-lin/all-example/tree/main/form-factory

如何动态生成组件?

比如传入的type: 'input'就会渲染Input组件,如果传入type: 'select'就会渲染Select组件,要怎么去完成这件事呢?

其实很多人第一时间会想到 Vue 的 <component>

其实一开始我也是使用这种方式去做的,但是发现一个问题,这样去做的话,那么插槽就做不了了~~

但是不同的 type 对应不同的 组件,这个思路是对的,所以需要维护一个对象

如何渲染插槽呢?

首先每个组件都会有自己的插槽,并且可能会重名,比如 Input 组件有 prefix 插槽,而 Select 也有 prefix 插槽,所以我们要防止冲突,就需要设置别名,比如下面的例子

  • Input 的 prefix 插槽,我别名成 input_prefix
  • Select 的 prefix 插槽,我别名成 select_prefix

接着只需要把别名插槽放进 FormFactory 里就行了

但是问题是内部的 Input 和 Select 不认 input_prefix 和 select_prefix,所以内部得把 input_prefix 和 select_prefix 转成 Input 和 Select 各自的 prefix

接着,你想要渲染插槽,用模板里的 component 可能有点难做,所以我使用了 Vue 的 h 方法,没有使用模板去做

如何更新状态

内部组件更新值得时候,也要更新传入的 model="formState",那么要怎么去做呢?我的做法是监听每一个表单组件的更新事件,然后更新对应的字段,并且要区分 formState 是 ref 还是 reactive,我是使用了 isRef 来判断

这里 reactive 的话我使用了 Object.assign 直接更新表单状态,大家如果有更好的方法的话,可以私信告诉俺下~

多组件库版本

我目前只做了 Ant-Design-Vue 版本,因为项目目前是使用了这个组件库,但是一个好的表单配置,肯定要配置多个组件库,所以我的想法是,设置一个基座,然后每一种组件库都做一个版本,基座通过 provide 把 config、options 传入各个版本中,用 inject 接收,然后拿着配置去做渲染

表单实例暴露

表单的实例 ref 也需要暴露出去,这样才能方便开发者使用表单身上的方法,灵活地对表单进行操作

在基座上,传入 setRef 方法

在各个版本的子项目中去设置实例

总结

思路差不多就是上面那样,至于具体实现可以看下面链接。

源码+示例:https://github.com/sanxin-lin/all-example/tree/main/form-factory

结语

我是林三心

Vue3项目中,如何设计一个表单配置生成器?

前端之神
一位前端小菜鸡,写过400多篇原创文章,全网有6w+个前端朋友,梦想是成为”前端之神“~
 最新文章