バックエンド管理システムを実行しているとき、非常に複雑なフォームに遭遇することがよくあります。
- フォーム項目が多すぎます
- さまざまなフォーム タイプでさまざまなフォーム項目を表示する
- 特定のフォーム項目は、特定の条件下で検証をオフにします
- 各フォーム項目には、テンプレート変数の挿入、入力文字数の表示、画像のアップロードと表示、リッチ テキストを実行できる入力ボックスなど、他のカスタム ロジックも含まれます。 。 。
- この複雑な状況では、フォームの確認と送信を完了してください。
- 具体的な例を参照できます。この例では、多くの簡単な関数が省略されており、ソリューションを示すために全体的な複雑なフォーム フレームワークのみが保持されています。
vue
ファイル内すべてのフォーム項目の表示と非表示、検証、データ取得、送信、カスタマイズ、その他のロジックがまとめられています。
- フォームの種類に応じて、
v-if/v-show
使用してフォーム項目の表示と非表示を処理します。elementui
カスタム検証では、フォーム タイプに基づいてフォーム アイテムが検証されるかどうかを決定します。- フォームの種類に応じて、異なるデータを取得し、異なるインターフェイスに送信します
- 他のすべてのカスタム ロジック
vue
ファイルには簡単に2000
行が含まれることがあります実際、異なるフォーム タイプに従って、対応するタイプの複数のサブフォームを分離することを考えるのは簡単です。しかし、実際には親子フォームの検証、送信されたデータ全体の取得など、依然として多くの問題に遭遇し、一連の解決策をまとめました。
すべての子コンポーネントには、親コンポーネントが呼び出すためのvalidate
メソッドとgetData
という 2 つのメソッドが含まれている必要があります。
validate
方法独自のコンポーネントのフォーム項目を検証し、 promise
オブジェクトを返すために使用されます。
vaildate ( ) {
// 返回`elementUI`表单验证的结果(为`promise`对象)
return this . $refs [ "ruleForm" ] . validate ( ) ;
} ,
getData
メソッド子コンポーネントからデータを提供する
getData ( ) {
// 返回子组件的form
return this . ruleForm ;
} ,
ストラテジ パターンを使用して、サブフォームのref
(サブフォームの取得に使用されるメソッド) と送信関数を保存および取得します。多くのif-else
判断が省略されます。
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
メソッド親子コンポーネントのフォーム検証、全体的なデータの取得、およびデータを送信するための現在のタイプ送信関数の呼び出しに使用されます。
elementUI
フォーム検証のvalidate
メソッドはpromise
結果を返すことができるため、promise
の特性を使用して親フォームと子フォームの検証を処理できます。 たとえば、then
関数は別のpromise
オブジェクトを返すことができ、catch
その上のすべてのthen
のreject
とPromise.all
を取得できます。
// 父表单验证通过才会验证子表单,存在先后顺序
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 ) ;
} ) ;
} ,
概要: 私は多くのプロジェクトでこの種の複雑なフォームに遭遇し、多くの解決策を使用してきました。ここでは、比較的すっきりとしたシンプルな解決策をまとめました。もちろん、他にも多くの解決策があります。たとえば、データ送信メソッドを各サブコンポーネントに配置し、パブリック フォーム項目データを送信用の
props
を通じてサブコンポーネントに渡すことができます。他にもっと簡単な解決策がある場合は、コメントしたり、github でissue
送信したりしてくださいgithub
余談: フロントエンド アーキテクト自身のアカウント: フロントエンド エンジニアの成長過程に関する N の質疑応答を読んで、とても刺激を受けました。自分の技術的な方向性や見通しについて混乱しているとき、プロジェクトのレベルが低すぎると不満を言うとき、毎日同じ作業を繰り返していると不満を言うとき、または毎日絶え間なく出現する新しいテクノロジーに圧倒されているとき、自分のプロジェクトを真剣に検討したほうがよいでしょう。
作業プロセスやプロジェクトの問題点から始めて、実際的な問題の実践、要約、解決をより早く進めることができます。
この記事を書いた感想:表現の難しさ
>>
記事自体に含まれる技術的な難しさ