Vue3 項(xiàng)目中,如何設(shè)計(jì)一個(gè)表單配置生成器?
背景
最近公司新開了一個(gè) Vue3 的項(xiàng)目,并且讓我做了組長(zhǎng),并且交待說可以開發(fā)一些基礎(chǔ)組件,提高整個(gè)團(tuán)隊(duì)的開發(fā)效率,于是我首先想到的是封裝一個(gè)表單配置組件,只需要傳入配置,就可以生成表單,減少組員的開發(fā)負(fù)擔(dān)~
源碼+示例:https://github.com/sanxin-lin/all-example/tree/main/form-factory
組員們說以前開發(fā)一個(gè)表單需要:模板寫組件,配置屬性,配置規(guī)則,獲取實(shí)例,邏輯分散等等操作,并且每個(gè)人都不統(tǒng)一,所以我才決定開發(fā)一個(gè)統(tǒng)一的表單配置組件~當(dāng)然這只是一個(gè)初步版本,后面會(huì)拓展其他新功能的!!!
這個(gè)表單配置組件已經(jīng)在項(xiàng)目中使用了,成員們都覺得大大提高開發(fā)效率,因?yàn)槭褂闷饋碚娴暮芎?jiǎn)單~初步調(diào)研,組員們說效率至少提升了30%!!!!!
具體使用方法如下,其實(shí)重要部分就四個(gè)部分:
1、表單選項(xiàng):options
2、表單配置:config
3、表單狀態(tài):formState
4、表單實(shí)例:formRef
定義完后,傳入 FormFactory 組件,便可以生成表單
思考
其實(shí)代碼不重要,我們要想想,實(shí)現(xiàn)這個(gè)東西需要注意哪些點(diǎn),思路是怎么樣的,想要看完整源碼和示例的,可以看這里
源碼+示例:https://github.com/sanxin-lin/all-example/tree/main/form-factory
如何動(dòng)態(tài)生成組件?
比如傳入的type: 'input'就會(huì)渲染Input組件,如果傳入type: 'select'就會(huì)渲染Select組件,要怎么去完成這件事呢?
其實(shí)很多人第一時(shí)間會(huì)想到 Vue 的 <component>
其實(shí)一開始我也是使用這種方式去做的,但是發(fā)現(xiàn)一個(gè)問題,這樣去做的話,那么插槽就做不了了~~
但是不同的 type 對(duì)應(yīng)不同的 組件,這個(gè)思路是對(duì)的,所以需要維護(hù)一個(gè)對(duì)象
如何渲染插槽呢?
首先每個(gè)組件都會(huì)有自己的插槽,并且可能會(huì)重名,比如 Input 組件有 prefix 插槽,而 Select 也有 prefix 插槽,所以我們要防止沖突,就需要設(shè)置別名,比如下面的例子
- Input 的 prefix 插槽,我別名成 input_prefix
- Select 的 prefix 插槽,我別名成 select_prefix
接著只需要把別名插槽放進(jìn) FormFactory 里就行了
但是問題是內(nèi)部的 Input 和 Select 不認(rèn) input_prefix 和 select_prefix,所以內(nèi)部得把 input_prefix 和 select_prefix 轉(zhuǎn)成 Input 和 Select 各自的 prefix
接著,你想要渲染插槽,用模板里的 component 可能有點(diǎn)難做,所以我使用了 Vue 的 h 方法,沒有使用模板去做
如何更新狀態(tài)
內(nèi)部組件更新值得時(shí)候,也要更新傳入的 model="formState",那么要怎么去做呢?我的做法是監(jiān)聽每一個(gè)表單組件的更新事件,然后更新對(duì)應(yīng)的字段,并且要區(qū)分 formState 是 ref 還是 reactive,我是使用了 isRef 來判斷
這里 reactive 的話我使用了 Object.assign 直接更新表單狀態(tài),大家如果有更好的方法的話,可以私信告訴俺下~
多組件庫版本
我目前只做了 Ant-Design-Vue 版本,因?yàn)轫?xiàng)目目前是使用了這個(gè)組件庫,但是一個(gè)好的表單配置,肯定要配置多個(gè)組件庫,所以我的想法是,設(shè)置一個(gè)基座,然后每一種組件庫都做一個(gè)版本,基座通過 provide 把 config、options 傳入各個(gè)版本中,用 inject 接收,然后拿著配置去做渲染
表單實(shí)例暴露
表單的實(shí)例 ref 也需要暴露出去,這樣才能方便開發(fā)者使用表單身上的方法,靈活地對(duì)表單進(jìn)行操作
在基座上,傳入 setRef 方法
在各個(gè)版本的子項(xiàng)目中去設(shè)置實(shí)例
總結(jié)
思路差不多就是上面那樣,至于具體實(shí)現(xiàn)可以看下面鏈接。
源碼+示例:https://github.com/sanxin-lin/all-example/tree/main/form-factory