配置化表單FormRender初嘗試
然而,我找到了一個非常好用的 表單 插件,就是通過下發JSON配置來生成表單視圖的方法!!!!
它就是 FormRender ,一站式中后臺 表單解決方案。
它有什么優點?
- 支持 Ant Design 和 Fusion Design 主流的視覺主題
- 使用JSON Schema 標準協議描述表單配置,并搭配豐富類型且可擴展的組件
- 支持 1 排 N、支持對象無限嵌套、自定義正則校驗、自定義樣式組件、列表拖拽等特性
- 已在飛豬、亞博科技、安全智能、淘寶、新零售行業工作臺、人工智能實驗室、天貓等多場景使用,可支持復雜場景使用
- 維護上有專人支持
香不香?我反正已經上手使用過了,是真的香!遇到這種靈活多變的表單配置化需求,一個輸入框和select都甚至需要封裝成一個組件,寫完一個組件,就要在components增加一個文件夾,要是用了這個插件,一些基礎的組件可以直接用,要是不滿足你的需求的話,也可以自定義組件(有這種類似場景的同學看過來,福利啊)
再講一下這個插件的缺點
插件誕生也就兩三年,可能會有一些bug,這是難免的 文檔不是很全 待發現... 但我目前用下來是沒啥大問題的
那么大家就會問呢?
實際開發復雜度有多高?
能支持復雜場景么?能支持聯動么?
能支持多樣化的定制需求么?
當然答案都是肯定的,接下來帶大家體驗一下
設計方案
協議層定義協議(schema)配置,展示層控制協議的渲染,工具層提供上下游的進一步支持。在此之上,FR 遵循如下的 api 設計:
基于JSON schema 的協議規范。JSON schema 作為 JSON 數據校驗表述的國際標準,主要用于表單數據的服務端校驗。已經接入JSON Schema標準的團隊可以幾乎無縫接入 FR。
極簡的組件 api:
這樣的設計下,FR 只負責管理和改動表單數據/時時校驗,而將具體如何使用表單數據和校驗信息乃至提交的方式全權交給了使用者自由書寫。
支持復雜聯動:
支持個性化擴展: 當出現現有表單元素無法滿足需求的場景,FR 使用自定義組件的方式,讓用戶自由擴展 FR 的組件庫。
備注:自定義組件就是普通的React組件,唯一的 要求是要有 value/onChange 這兩個 props,用于雙向綁定值。所以如果現成的組件已經默認使用了 value/onChange,就可以直接拿來用。
協議上只需指明"widget": "MyInput",即可使用對應的組件來渲染:
一句話總結,基于 JSON schema 的協議確保了 FR 的規范性,可控組件的模型確保了外層 api 的簡潔和解耦,聯動&自定義組件的 api 確保了對大量復雜的場景的很好支持。
下面我來談談小伙伴們最關心的實際使用體感吧。
使用體驗 & 流程
安裝:
FormRender 依賴 ant design,單獨使用不要忘記同時安裝 antd
npm i form-render --save
最簡demo
從 demo 中我們不難發現 FormRender 的一些設計:
- 以 schema 來描述表單展示,提交方式與 antd v4 的方式類似。
- schema 以國際標準的 JSON schema 為基礎,同時能夠方便使用任何 antd 的 props。
- 通過bind字段,我們允許數據的雙向綁定,數據展示和真實提交的數據可以根據開發需求不同(例如從服務端接口拿到不規則數據時,也能直接使用)。
- 使用{{...}}書寫表達式來完成簡單的聯動,值得一提的是,這里表達式支持所有 js 語法。FR 還提供自定義組件、dependencies 聲明、watch 等工具用于更加復雜的定制。
- 可以通過displayType,labelWidth等字段輕易修改展示。
通過使用 schema 編輯器,生成一個表單的流程非常簡單,有興趣的同學可以按下面示例在線嘗試一下,體會它的強大性:
- 使用 在線 schema 編輯器 搭建表單,導出 schema
- 將 schema 作為props傳入<FormRender {...schema} />組件 在線(demo中替換 schema.json 文件內容即可)。
在原有的基礎組件支撐下,我們需要一個復雜聯動的自定義組件,如圖:
當時在封裝這個自定義組件時遇到的一個小坑:
如上圖標注,組件只掛載了一次,導致給自定義組件傳的recycleLinkCode,剛開始拿到的初始值是空,但是組件已經掛載完了,等到接口返回recycleLinkCode的值時,傳過去的數據沒有實時更新。
官方給出的理由是: formData的更新才會觸發表單的重新渲染,但是recycleLinkCode不是表單值,所以不能用form.setValues和form.setValueByPath來修改表單值
解決辦法:
接口拿到數據之后再去加載組件;
觸發組件重新渲染,可以試試這樣寫:useMemo(()=>,[recycleLinkCode])。
寫在最后
總體來說這個插件已經很 nice 了,可以滿足一般表單基本的需求。使用拖拽形式,也完全可以交給產品運營同學直接進行表單配置組合。