When we are doing backend management systems, we often encounter very complex forms:
- There are too many form items
- Display different form items under various form types
- Certain form items turn off validation under certain conditions
- Each form item will also have other custom logic, such as input boxes that can insert template variables, display the number of input characters, upload and display images, and rich text . . .
- In this complicated situation, complete the verification and submission of the form
- You can view specific examples: Many trivial functions are omitted in the example, and only the overall complex form framework is retained to demonstrate the solution.
vue fileAll form item display and hiding, validation, data acquisition, submission, customization and other logic are put together
- According to the form type, use
v-if/v-showto handle the display and hiding of form items.- In
elementuicustom validation, determine whether the form item is validated based on the form type- According to the form type, obtain different data and submit it to different interfaces
- All other custom logic
vue file can easily contain 2000 linesIn fact, it is easy to think of separating multiple subforms of corresponding types according to different form types . But I still encountered many problems in practice: parent-child form verification, obtaining overall submitted data , etc., and summarized a set of solutions:
All child components need to contain two methods validate and getData for the parent component to call.
validate method Used to verify the form items of its own components and return a promise object
vaildate ( ) {
// 返回`elementUI`表单验证的结果(为`promise`对象)
return this . $refs [ "ruleForm" ] . validate ( ) ;
} ,
getData methodProvide data from child components
getData ( ) {
// 返回子组件的form
return this . ruleForm ;
} , Use the strategy pattern to store and get ref of the subform (the method used to get the subform) and the submit function . A lot of if-else judgments are omitted.
data: {
// type和ref名称的映射
typeRefMap : {
1 : "message" ,
2 : "mail" ,
3 : "apppush"
} ,
// type和提交函数的映射。不同类型,接口可能不同
typeSubmitMap : {
1 : data => alert ( `短信模板创建成功${ JSON . stringify ( data ) } ` ) ,
2 : data => alert ( `邮件模板创建成功${ JSON . stringify ( data ) } ` ) ,
3 : data => alert ( `push模板创建成功${ JSON . stringify ( data ) } ` )
} ,
} submit methodUsed for parent-child component form validation, obtaining overall data, and calling the current type submission function to submit data
Because the
validatemethod ofelementUIform verification can return apromiseresult , you can use the characteristics ofpromiseto handle the verification of parent and child forms. For example, thethenfunction can return anotherpromiseobject, andcatchcan obtainrejectandPromise.allof allthenabove it.
// 父表单验证通过才会验证子表单,存在先后顺序
submitForm ( ) {
const templateType = this . typeRefMap [ this . indexForm . type ] ;
this . $refs [ "indexForm" ]
. validate ( )
. then ( res => {
// 父表单验证成功后,验证子表单
return this . $refs [ templateType ] . vaildate ( ) ;
} )
. then ( res => {
// 全部验证通过
// 获取整体数据
const reqData = {
// 获取子组件数据
... this . $refs [ templateType ] . getData ( ) ,
... this . indexForm
} ;
// 获取当前表单类型的提交函数,并提交
this . typeSubmitMap [ this . indexForm . type ] ( reqData ) ;
} )
. catch ( err => {
console . log ( err ) ;
} ) ;
} , submitForm1 ( ) {
const templateType = this . typeRefMap [ this . indexForm . type ] ;
const validate1 = this . $refs [ "indexForm" ] . validate ( ) ;
const validate2 = this . $refs [ templateType ] . vaildate ( ) ;
// 父子表单一起验证
Promise . all ( [ validate1 , validate2 ] )
. then ( res => {
// 都通过时,发送请求
const reqData = {
... this . $refs [ templateType ] . getData ( ) ,
... this . indexForm
} ;
this . typeSubmitMap [ this . indexForm . type ] ( reqData ) ;
} )
. catch ( err => {
console . log ( err ) ;
} ) ;
} , Summary: I have encountered this kind of complex forms in many projects and used many solutions. Here I have summarized a relatively neat and simple solution. Of course, there are many other solutions. For example , the data submission method can be placed in each sub-component, and the public form item data is passed to the sub-component through
propsfor submission . If there are other simpler solutions, you are welcome to comment or submitissueongithub
Off-topic: After reading the front-end architect’s own account: N’s question and answer on the growth path of a front-end engineer, it inspired me a lot. When you are confused about your technical direction and prospects, or when you complain that your project is too low, or when you complain that you are doing repetitive work every day, or when you are overwhelmed by the endless emergence of new technologies every day , you might as well take a serious look at your project .
Starting from the pain points of work processes and projects , you will make faster progress in practicing, summarizing and solving practical problems .
My feelings about writing this article: the difficulty of expressing these things
>>the technical difficulty contained in the article itself