摘要:是校驗表單組件數(shù)據(jù)正確性的字段,其值為數(shù)組,里面的數(shù)組元素可以為。所以數(shù)組元素如果為的話,其內(nèi)容就是的。到目前為止,表單適合大部分的表單應(yīng)用場景。
JSON表單 描述
JSON表單是一個基于React的抽象組件,它可以把JSON數(shù)據(jù)格式描述的表單轉(zhuǎn)換成項目中的表單,它可以用簡短的幾行代碼,快速的生成Form表單。
JSON表單的優(yōu)點是:
可以快速構(gòu)建出一個表單
表單的數(shù)據(jù)、邏輯、視圖分離,方便抽離和進(jìn)一步抽象
提供校驗、自動緩存等額外功能,提升錄入體驗
可以跨項目的共用復(fù)雜的表單組件
原始表單的缺點1:代碼量龐大,開發(fā)效率低
每次開發(fā)一個表單頁的時候,都需要重復(fù)編寫表單組件及其交互事件的代碼,這塊代碼重復(fù)編寫且與主線業(yè)務(wù)邏輯無關(guān),除此之外,表單的校驗、緩存等額外功能,也需要不少的代碼量,這樣就造成了一個表單頁的代碼量龐大。
2:不便于抽離和進(jìn)一步的抽象
在一個表單頁內(nèi),往往會將表單數(shù)據(jù)、表單組件、控制邏輯雜糅在一起,當(dāng)發(fā)現(xiàn)某一個子功能在很多場景下都需要用到的時候,想把該子功能拆分出來發(fā)現(xiàn)并不容易,因為邏輯、數(shù)據(jù)、視圖的雜糅,導(dǎo)致想把子功能不受影響的剔除出來需要很仔細(xì)的檢查,這樣就導(dǎo)致功能的抽離和抽象的不便
3:維護(hù)成本高
這個和第二個問題是同樣的原因,這也是我的親身經(jīng)歷,當(dāng)我在項目中想優(yōu)化一個小功能的時候,發(fā)現(xiàn)不僅把之前的邏輯改沒了,還引出了不少的bug,這導(dǎo)致在一個邏輯很復(fù)雜的表單里,維護(hù)變成了一件高危工作。
4:需要額外處理校驗和緩存等功能
如何使用其github地址為:json_transform_form。
依賴環(huán)境React 基于React
async-validator 基于它做校驗
安裝npm i json_transform_form --save一個栗子
import Form from "json_transform_form" const config = { formKey: "example-form", data: { name: "", descr: "", typeName: "" }, config: [ { type: "input", dataKey: "name", label: "param", placeholder: "請輸入param", validate: ["required", /^[a-zA-Z_{}0-9]+$/g], style: { display: "inline-block", width: 270, }, }, { type: "select", dataKey: "typeName", options: ["string", "integer", "float"], style: { display: "inline-block", width: 100, margin: "0 15px" }, validate: [{type: "required", message: "param類型不能為空"}] }, { type: "textarea", dataKey: "descr", placeholder: "請輸入param含義", label: "param含義", validate: ["required"], style: { width: 385, } }, ] }this.FormWrap = ref} config={config}>
上面是用JSON描述的三個常用的表單組件組合成的表單,其效果圖如下:
{ formKey: "paramAddForm", data: {}, config: [] }
屬性 | 是否必傳 | 說明 | 類型 | 默認(rèn)值 |
---|---|---|---|---|
formKey | 否 | 用來自動緩存,localStorage的key,不傳表示不自動緩存 | string | - |
className | 否 | 用來添加一些自定義樣式 | string | - |
data | 是 | 表單的提交數(shù)據(jù),有自動緩存和校驗功能 | object | - |
assisData | 否 | 用于表單控制邏輯的額外數(shù)據(jù) | object | - |
config | 是 | 組件配置,表單組件的配置 | Array | - |
realTimeSubmit | 否 | 表單是否實時提交,一般用于篩選表單 | boolean | false |
{ type: "input", dataKey: "name", label: "param", validate: ["required"], style: {} }
屬性 | 是否必傳 | 說明 | 類型 | 默認(rèn)值 |
---|---|---|---|---|
type | 是 | 表單組件的類型,其值可以為: input、select、textarea、form_array、container和一些自定義表單組件 | string | - |
dataKey | 否 | 指定表單組件值的key,可以為param.name.firstName形式 | string | - |
label | 否 | 表單組件的label | string | - |
placeholder | 否 | 表單組件的placeholder | string | - |
validate | 否 | 表單組件的校驗規(guī)則 | Array | - |
style | 否 | 表單組件的布局樣式 | string | - |
options | 否 | 當(dāng)表單組件為select時,需要傳入的options | Array | - |
render | 否 | 當(dāng)type為container時,為自定義組件,render為渲染方法 | Function | - |
preventSubmit | 否 | 當(dāng)realTimeSubmit為true時,控制當(dāng)前表單組件是否實時提交 | boolean | false |
children | 否 | 當(dāng)type為form_array時,children表示子組件配置列表 | Array | - |
modifyDataFn | 否 | 當(dāng)type為自定義組件時,且需要覆蓋render方法中的提交數(shù)據(jù)方法,可以使用modifyDataFn來重新自定義提交數(shù)據(jù) | Function | - |
type是用來唯一表示表單組件類型的字段,其中JSON表單提供了三種默認(rèn)的表單組件:input、select、textarea,還有兩種復(fù)雜類型的表單組件:form_array、container。
form_array表單組件表示其數(shù)據(jù)結(jié)構(gòu)為Array,含有增加項刪除項的復(fù)合表單組件,該表單組件的配置里多一個children的字段,里面是每一項里面的表單組件配置的集合,其表單組件的效果如下圖所示:
container是用來自定義表單的接口,具體用法參考下面具體的介紹。
2. validatevalidate是校驗表單組件數(shù)據(jù)正確性的字段,其值為數(shù)組,里面的數(shù)組元素可以為String、object、RegExp、Function。
JSON表單采用的是async-validator異步處理校驗,在JSON表單內(nèi)部會將validate傳入的校驗關(guān)鍵字解析為async-validator的rules。所以validate數(shù)組元素如果為object的話,其內(nèi)容就是async-validator的rules。
1. 數(shù)組元素為string,其值可以為: string,值必須為string number,值必須為數(shù)字 required,值不能為空 boolean,值必須為布爾值 integer,值必須為整數(shù)形 float,值必須為浮點型 email,值必須為郵箱類型 2. 數(shù)組元素為object,其值為rules: {type: "enum", enum: ["1", "2"], message: "值不在確定范圍內(nèi)"} 3. 數(shù)組元素為RegExp, validate: [/^[a-zA-Z_{}0-9]+$/g] 4. 數(shù)組元素為Function, validate: [ (rules, value, callback) => {}]3. style
用來確定表單組件在表單內(nèi)的布局樣式,比如想讓表單組件行內(nèi)顯示,且寬度為200,其style值如下:
{ display: "inline-block", width: 200 }container表單組件
container表單組件是用來自定義表單組件的,它主要的作用有以下幾點:
添加表單組件庫,例如Ant-Design
自定義表單組件,例如圖片上傳組件
用來構(gòu)建復(fù)雜的表單組件
處理控制邏輯和聯(lián)動邏輯
使用栗子import { Input, Select } from "antd" const Option = Select.Option { type: "container", dataKey: "descr", style: { display: "inline-block", width: 100, margin: "0 15px" }, options: ["string", "integer", "float"], render: (curData, config, {changeFn, getFocus, loseFocus, error}) => { return } },
container表單組件只是多一個render渲染方法,里面可以自定義表單組件的渲染內(nèi)容,render方法提供如下參數(shù):
1. curData: 當(dāng)前container組件的值,跟dataKey相關(guān) 2. config: 當(dāng)前container組件的配置 3:{changeFn, changeDataFn, getFocus, loseFocus, error, JSONForm} changeFn, changDataFn是提交數(shù)據(jù)的方法,changeFn只能修改當(dāng)前組件dataKey的值,changeDataFn可以修改data中任意字段的值,changeFn(value, [callback]), changeFn(dataKey, value, [callback]) getFocus,loseFocus是自定義處理校驗的字段,loseFocus是開始校驗,getFocus是去掉校驗的報錯信息 error是校驗結(jié)果的報錯信息 JSONForm是在container中使用JSON表單的組件配置用來生成新的表單組件,意思里container中依然可以嵌套表單組件。使用antd的組件庫
JOSN表單只提供了input、select、textarea三種默認(rèn)的表單組件,遠(yuǎn)遠(yuǎn)不夠真實的項目中使用,所以我們可以將antd組件庫中的組件封裝到JSON表單中,這樣我們就可以再項目中很快的使用antd中的組件。
antd-components.js
import React from "react" import { Input } from "antd" export default [ { type: "antd-input", render: (curData, config, {changeFn, getFocus, loseFocus, error}) => { return changeFn(event.target.value)} /> } } ]
我們在antd-components.js文件中聲明一個antd-input的自定義組件,然后在JSON表單中引入該自定義表單組件:
init.js
import Form from "json_transform_form" import components from "./antd-components" From.createCustomComp(components) const config = { formKey: "paramAddFromAntd", data: { name: "", }, config: [ { type: "antd-input", dataKey: "name", label: "Param", placeholder: "請輸入param", validate: ["required", /^[a-zA-Z_{}0-9]+$/g] } ] }this.FormWrap = ref} config={config}>
使用container來引入antd組件庫,其原理就是通過container將antd組件封裝成"antd-input"自定義組件,然后使用它,這種方式不僅可以用來封裝組件庫,還可以用來共享一些共用表單組件,可以將常用的復(fù)雜表單組件封裝在一個共用文件里,然后在不同項目中引用,就可以跨項目共用表單組件。
在自定義組件中,如果需要自定義表單提交數(shù)據(jù)函數(shù),但是又不能重寫render方法以防覆蓋原先的render方法,所以可以使用modifyDataFn方法來覆蓋render中的提交數(shù)據(jù)部分。
modifyDataFn: ({changeFn, changeDataFn}, {parent, self}) => { let {parentData} = parent parentData = parentData.map(item => ({ ...item, name: self.curData })) changeDataFn(parent.parentKey, parentData) }處理控制邏輯和聯(lián)動邏輯
在JSON表單JSON配置中,有assistData的選填字段,該字段為JSON表單處理控制邏輯的額外數(shù)據(jù),例如在表單內(nèi)有一個刷新按鈕,其實現(xiàn)代碼如下:
{ data: {}, assistData: { refreshParam: false }, config: [ { type: "container", dataKey: "assistData.refreshParam", render: (curData, config, {changeFn, changeDataFn}) => { const handleClick = () => { changeDataFn("assistData.refreshParam" ,true) setTimeout(() => { changeDataFn("assistData.refreshParam" ,false) }, 1000 * 3) } return{ config.index === config.parentData.length - 1 && } }, ] }}
注意: 如果要使用assistData中的數(shù)據(jù),其dataKey必須以assistData開頭,且必須使用changeDataFn自定義提交assistData數(shù)據(jù)。
render方法內(nèi)嵌套組件配置{ type: "container", dataKey: "param", render: (curData, config, {changeFn, changeDataFn, JSONForm}) => { return{ JSONForm([ { type: "input", dataKey: "name", placeholder: "請輸入param", validate: ["required"], } ]) }}
這樣就可以在container內(nèi)嵌套組件配置,實現(xiàn)更復(fù)雜的表單組件。
JSON表單提交數(shù)據(jù) 非實時表單提交非實時表單提交數(shù)據(jù),就是在表單輸入完畢后,點擊提交按鈕統(tǒng)一提交所有的數(shù)據(jù),其提交的方式如下:
function handleClick() { this.FormRefs.getValue((valid, data) => { // valid 表示校驗結(jié)果,false表示校驗不通過 }) }實時表單提交
實時表單的提交首先需要注冊提交函數(shù):
componentDidMount(){ this.FormRefs.registerSubmit((valid, data) => { console.log(valid, data) }) }
接著在配置里設(shè)置允許實時提交的字段:
{ formKey: "", realTimeSubmit: true }
如果需要在某些表單組件里自定義是否實時提交,需要在組件配置里設(shè)置阻止實時提交字段為true:
{ dataKey: "", preventSubmit: true }JSON表單的應(yīng)用場景 表單分類
a. 按復(fù)雜度分類 1. 簡單表單:表單組件為input、select、textarea等常見的幾種,且表單組件之間邏輯獨立 2. 復(fù)雜表單:表單組件內(nèi)容和交互復(fù)雜且相互之間存在復(fù)雜的邏輯 其中復(fù)雜表單又可以分為: 1. 聯(lián)動表單,上一個表單組件會影響接下來表單的值 2. 實時表單,表單組件的事件會觸發(fā)表單的實時提交,例如篩選表單 3. 富控制表單,表單內(nèi)部含有很多的控制邏輯
JSON表單最適合的應(yīng)用場景是簡單表單,它可以用極少的代碼,快速的構(gòu)建出表單來,對于復(fù)雜類型的表單,JSON表單需要使用container來構(gòu)建復(fù)雜的表單組件、處理復(fù)雜的控制邏輯,其代碼量優(yōu)勢雖然并不明顯,但是JSON表單可以使其代碼清晰,將表單組件和表單邏輯徹底解耦,便于抽離和維護(hù),便于共享常用組件,也帶來不少的好處。
到目前為止,JSON表單適合大部分的表單應(yīng)用場景。
JSON表單解決的問題減少了表單代碼量,不需要重復(fù)的開發(fā)表單組件,只需要輸入組件配置即可
將表單組件和數(shù)據(jù)解耦,便于子功能的拆分和常用組件的共享
簡化了校驗功能,只需要傳入validate字段即可
添加了自動緩存功能
在我的項目,我嘗試了使用原始表單和JSON表單兩種方式來實現(xiàn)同一個表單頁,原始表單我編寫了600多行的代碼,而在JSON表單中,只有不到150行。
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/108684.html
摘要:介紹表單是一個基于的抽象組件,它能將格式的配置渲染為一個表單,在實際項目中,通過它可以快速的搭建出一個表單頁,這在端項目中,有著很廣泛的用途。如何使用表單的地址為。 介紹 JSON表單是一個基于React的抽象組件,它能將JSON格式的配置渲染為一個Form表單,在實際項目中,通過它可以快速的搭建出一個表單頁,這在B端項目中,有著很廣泛的用途。 JSON表單的優(yōu)點有以下幾點: 可以快...
摘要:配置表單的配置分為兩種,暫且稱描述表單信息的為表單配置,描述表單組件信息的為組件配置。組件組件主要是用來描述組件數(shù)據(jù)為數(shù)組格式的表單組件,其示例如下組件配置是基于父表單組件其效果圖如下表單的表單組件請看下節(jié)生成表單三 JSON配置 JSON表單的配置分為兩種,暫且稱描述表單信息的為表單配置,描述表單組件信息的為組件配置。JSON表單的配置一定是兩種配置的組合。 在開始講解配置之前先介紹...
摘要:表單實例方法靜態(tài)方法表單有一個靜態(tài)方法方法時表單的靜態(tài)方法,用來引入抽象出來的表單組件。首先需要開啟實時表單提交,在表單配置中設(shè)置為。到目前為止,表單適合大部分的表單應(yīng)用場景。 JSON表單實例方法 靜態(tài)方法 json表單有一個靜態(tài)方法:createCustomComp import Form from json_transform_form import components fro...
摘要:嵌套組件配置如果表單組件里還含有其他表單組件,這時直接通過組件配置去渲染無疑能節(jié)約不少的工作量。請輸入方法傳入組件配置的列表就能渲染出表單組件來,需要注意的是,子表單組件的一定是基于父表單組件的。表單的實例方法請看下節(jié)的生成表單四 container表單組件 在實際的項目中,JSON表單提供的表單組件是遠(yuǎn)遠(yuǎn)不夠的,而且提供表單組件是一件低效的事,目前Ant Design組件庫提供的表單...
摘要:介紹是一個可以通過生成具有動態(tài)渲染數(shù)據(jù)收集驗證和提交功能的表單生成器。并且支持生成任何組件。結(jié)合內(nèi)置種常用表單組件和自定義組件,再復(fù)雜的表單都可以輕松搞定。 介紹 form-create 是一個可以通過 JSON 生成具有動態(tài)渲染、數(shù)據(jù)收集、驗證和提交功能的表單生成器。并且支持生成任何 Vue 組件。結(jié)合內(nèi)置17種常用表單組件和自定義組件,再復(fù)雜的表單都可以輕松搞定。 文檔 | git...
閱讀 2895·2021-10-26 09:49
閱讀 3230·2021-10-14 09:42
閱讀 2056·2021-09-13 10:31
閱讀 2599·2019-08-30 11:13
閱讀 2971·2019-08-29 16:31
閱讀 1086·2019-08-29 13:58
閱讀 1869·2019-08-29 12:12
閱讀 3595·2019-08-26 13:48