Vue+ElementUIによる大規模なフォームの処理例
2022-01-13 21:21:02
最近、業務再編により、以前の超長文フォームのロジックに変更が増えたので、リファクタリングを計画しました(退社したバックエンドが書いたもので、コメントもなく、コンポーネントが4000行以上書いてあり、本当に大変でした)。読むのに便利なように、ここではプロジェクトを14個のコンポーネントに分割して合理化しました。
全体像
/{h3
-
大きな帳票は、業務モジュールごとに分割
-
el-formが提供するvalidateメソッドで保存する(分割された各コンポーネントをループする)
-
mixin 各コンポーネントのコモン抽出(後のプロジェクトメンテナンスにも便利です)
スタート
フォーム1、フォーム2という2つのコンポーネントを分割する例です(読者の便宜を図るため、名前は伏せ字にしています)。
ここで、なぜref、モデルバインディング、フォームの2つのコンポーネントなのかは、後で説明します(後のメンテナンスを容易にするため)。
// form1 component
<template>
<el-form
ref="form"
:model="form"
label-width="10px"
>
<el-form-item label="name" prop="name">
<el-input v-model="form.name" />
</el-form-item>
</el-form>
</template>
<script>
export default {
name: 'Form1',
props: {
form: {}
},
data() {
return {
rules: {
name: [
{ required: true, message: 'Please enter your name', trigger: 'blur' }
]
}
}
},
methods: {
// This is for the parent component to loop through the checksum calls
validForm() {
let result = false
this.$refs.form.validate(valid => valid && (result = true))
return result
}
// I also used another way to write it here, but the loop check is a promise object, there is a problem, hope the big guys point out a couple of things
validForm() {
// Obviously the output structure here is Boolean, but after the parent component loop call it's a promise type, need to convert it to work
return this.$refs.form.validate().catch(e => console.log(e))
}
}
}
</script>
// form2 component
<template>
<el-form
ref="form"
:model="form"
label-width="10px"
>
<el-form-item label="age" prop="age">
<el-input v-model="form.age" />
</el-form-item>
</el-form>
</template>
<script>
export default {
name: 'Form2',
props: {
form: {}
},
data() {
return {
rules: {
name: [
{ required: true, message: 'Please enter your age', trigger: 'blur' }
]
}
}
},
methods: {
// This is for the parent component to loop through the checksum calls
validForm() {
let result = false
this.$refs.form.validate(valid => valid && (result = true))
return result
}
}
}
</script>
親コンポーネントがどのように参照されているか見てみましょう
// parent component
<template>
<div class="parent">
<form1 ref="form1" :form="formData.form1" />
<form2 ref="form2" :form="formData.form2" />
<el-button type="primary" @click="save"> report error</el-button>
</div>
</template>
<script>
... Omit the reference
export default {
name: 'parent',
... Omit registration
data () {
return {
formData: {
form1: {},
form2: {}
}
}
},
}
</script>
formDataの属性名form1, form2はサブフォームコンポーネントのrefで使われているので、トラバースするときに順番に見つけて、以下のコードで保存関数を修正します。
methods: {
save () {
// The key value of each form object, which is the ref value of each form
const formKeys = Object.keys(this.formData)
// Execute each form's validation method
const valids = formKeys.map(item => this.$refs[item].validForm())
// Logic after all forms pass the validation
if (valids.every(item => item)) {
console.log(11)
}
}
}
コンポーネント ref と model の両方がフォームにバインドされている理由を解決します。
- 比較の結果、form1 form2 は共通の props メソッドを持っていることがわかります。
- それをMixinで抽出してみましょう
export default {
props: {
form: {
required: true,
type: Object,
default: () => {}
},
},
methods: {
validForm () {
let result = false
this.$refs.form.validate(valid => valid && (result = true))
return result
}
}
}
form1 form2 の minix を参照し、対応するコンポーネントの対応するプロパティとメソッドを削除します。
エンディング
- オーバーサイズのフォームを解決するのは難しいので、ここではコンポーネントを分割しているだけです。
- 部品間の連携も大きな難点なので、次回は完成後に発信します
今回はVue+ElementUIの大きなフォームへの対応例について紹介しましたが、より関連するVue+ElementUIの大きなフォームへの対応内容についてはBinaryDevelopの過去記事を検索するか、以下の関連記事を引き続き閲覧してください。
関連
-
vue3レスポンシブ対応のためのsetup+ref+reactive
-
Vueがechartsのtooltipにクリックイベントを追加するケーススタディ
-
Vue Element-uiは、アイコンを追加するためのツリーコントロールノードを詳細に実装しています。
-
元のイベントが実行されなかった後に要素を追加するためのjQueryソリューション
-
jQueryのコピーオブジェクトの説明
-
vueのグローバルがscss(mixin)を導入。
-
vue+webrtc(Tencent cloud)ライブ機能の実践を実現するために
-
vueにおけるv-forループオブジェクトのプロパティ
-
VUEグローバルフィルターの概念と留意点、基本的な使い方
-
Vueでルートネスティングを実装する例
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン