ベストプラクティス:vue弾窓およびスライダ応答式
23932 ワード
下記は項目中の弾窓/スライダ統一処理方式まとめ(下記el-dialogを例に挙げる)
プレゼンテーション環境:https://eugvd.csb.app/Demoアドレス:https://codesandbox.io/s/thirsty-sun-eugvd?file=/src/components/User.vue:2122-2497
DOM構造
方式1.(推奨1:直接データ注入「詳細」)el-dialogシェルは外にあり、内容は個別のコンポーネントであり、後続のコンポーネントは他のシェルに置き換えることができる
方式2.(推奨2)el-dialogシェルは外にあり、内容は個別のコンポーネントであり、後続のコンポーネントは他のシェルに置き換えることができる.
方式3.(推奨しない)el-dialogコンポーネント内部
レスポンスモード
前提:コンポーネント内でデータを要求しない–推奨1:直接データを注入する「詳細」
現在のrowまたはコンポーネント外でデータを取得する場合は、本明細書で説明する範囲外で直接伝達すればよい(詳細は通常、このようなシーンである).
例:新規/編集は同じコンポーネントを使用します.(推奨2)el-dialogシェルは外にあり、コンテンツは個別のコンポーネントで、後続のコンポーネントは他のシェルに置き換えることができます.
質問:データはトリガ要求に応答する、特に同一ID及び区別新規(要求不要)/編集状況 に注意する.フォームエラープロンプト語がクリアされ、特に最初の呼び出し時に
イニシアチブ
シナリオ1.(無効)
シナリオ2.(推奨しない)
シナリオ3.(推奨しない)
シナリオ4. の利点:要求が正確で、追加の要求は存在しない 劣勢:idとwatchを傍受する必要があり、処理がやや複雑な シナリオ5.傍受利点:エラーメッセージのクリア、統一処理、簡単な を実現劣勢:同じID編集で、1回目は保存しない(情報は変化していない)、2回目は開いても を要求する.
補足:上記「シナリオ5」に対して、切替IDポップアップ表示状態が変化しないため、同時にIDを傍受する必要がある.
下記は
えんちょうもんだい
編集は新規と同じポップアップウィンドウで、編集してから新規に追加します.現在のポップアップウィンドウはv-show形式であるため、保存時に余分な属性がコミットされます(IDなど).特に、el-form
シナリオ1:(煩雑)formオブジェクトをJSONシーケンス番号と逆シーケンス(コピー)する
シナリオ2:(制限)コミット時にidを削除する(編集が新規属性よりも多くなると冗長になる)
シナリオ3:(推奨)
リファレンスアドレス Add a function to reset a component’s state–Vue公式Issues、そのうち特に大きな返事 el-form-itemとformクリア値全体の問題–ElementUI公式Issues
プレゼンテーション環境:https://eugvd.csb.app/Demoアドレス:https://codesandbox.io/s/thirsty-sun-eugvd?file=/src/components/User.vue:2122-2497
DOM構造
方式1.(推奨1:直接データ注入「詳細」)el-dialogシェルは外にあり、内容は個別のコンポーネントであり、後続のコンポーネントは他のシェルに置き換えることができる
<template>
<el-dialog
title=" "
:visible.sync="centerDialogVisible"
width="30%"
center>
<my-component :visible.sync="centerDialogVisible" :data="xxxx">my-component>
<span slot="footer">
<el-button @click="centerDialogVisible = false"> el-button>
<el-button type="primary" @click="centerDialogVisible = false"> el-button>
span>
el-dialog>
template>
方式2.(推奨2)el-dialogシェルは外にあり、内容は個別のコンポーネントであり、後続のコンポーネントは他のシェルに置き換えることができる.
<template>
<el-dialog
title=" "
:visible.sync="centerDialogVisible"
width="30%"
center>
<my-component :visible.sync="centerDialogVisible" :id="editId">my-component>
el-dialog>
template>
方式3.(推奨しない)el-dialogコンポーネント内部
<my-component :visible.sync="centerDialogVisible" :id="editId">my-component>
レスポンスモード
前提:コンポーネント内でデータを要求しない–推奨1:直接データを注入する「詳細」
現在のrowまたはコンポーネント外でデータを取得する場合は、本明細書で説明する範囲外で直接伝達すればよい(詳細は通常、このようなシーンである).
例:新規/編集は同じコンポーネントを使用します.(推奨2)el-dialogシェルは外にあり、コンテンツは個別のコンポーネントで、後続のコンポーネントは他のシェルに置き換えることができます.
質問:
$refs['xxx']
がまだ存在しない可能性があることに注意する.イニシアチブ
シナリオ1.(無効)
v-if + created/mounted
書き方は簡単ですが、性能が非常に悪く、やむを得ず使用を根絶しました!!!シナリオ2.(推奨しない)
:key
は性能的にv-if
よりずっと良いですが、ここのシーンでは、データ応答が解決され、DOM(仮想DOM)とはあまり関係ありません.<my-component :visible.sync="centerDialogVisible" :id="editId" :key="editId">my-component>
シナリオ3.(推奨しない)
refs.xxx.init()
呼び出し.2つの問題:最初の呼び出しタイミングは、await this.$nextTick()
が必要になることが多い.コンポーネントの内部メソッドは外部要素によって呼び出され、結合度が高く、メンテナンスとアップグレードのコストを制御できません.シナリオ4.
id
の変更を傍受し、id
の要求に従ってデータ編集保存に成功し、現在の行をクリックすると、idは変更されず、データが変更前の=>>保存に成功した後、id = undefined
、キャンセルまたはクローズは処理されません.props: ['id'],
watch: {
id: {
handler (val, oldVal) {
// id undefined
if (val) {
this.requestData(val) //
}
},
immediate: true
},
visible: {
handler (val, oldVal) {
!val && this.resetForm()
},
immediate: true
}
}
visible
が変更され、visible
に従ってデータが要求されるprops: ['id', 'visible'],
watch: {
visible: {
handler(val, oldVal) {
!val && this.resetForm()
if (val && this.id) {
this.getUserById()
}
},
immediate: true
}
}
補足:上記「シナリオ5」に対して、切替IDポップアップ表示状態が変化しないため、同時にIDを傍受する必要がある.
下記は
watch function
の形式を採用している.ここでは同時にcomputed + watch
形式を採用することができるcreated() {
this.unwatch = this.$watch(
() => {
return [this.id, this.visible];
},
(val, oldVal) => {
let [id, visible] = val
!visible && this.resetForm();
if (visible && id) {
this.getUserById();
}
},
{
immediate: true
}
);
},
beforeDestroy () {
this.unwatch()
}
えんちょうもんだい
編集は新規と同じポップアップウィンドウで、編集してから新規に追加します.現在のポップアップウィンドウはv-show形式であるため、保存時に余分な属性がコミットされます(IDなど).特に、el-form
resetFields()
はシーンを処理するものではなく、el-form-item propプロパティ値のみをリセットします.シナリオ1:(煩雑)formオブジェクトをJSONシーケンス番号と逆シーケンス(コピー)する
const userForm = {
name: "",
province: ""
}
export default {
name: "User",
props: ["visible", "id"],
data() {
return {
userForm: JSON.parse(JSON.stringify(userForm)),
rules: { ... }
};
},
methods: {
resetForm() {
this.$refs.userForm.resetFields();
this.userForm = JSON.parse(JSON.stringify(userForm));
}
}
}
シナリオ2:(制限)コミット時にidを削除する(編集が新規属性よりも多くなると冗長になる)
// 「 」 「 」
delete this.userForm.id
...
シナリオ3:(推奨)
this.$options.data()
で還元resetForm() {
this.$refs.userForm.resetFields();
this.userForm = Object.assign({}, this.$options.data().userForm);
}
// , this
const data = this.$options.data()
Object.keys(data).forEach(key => {
this[key] = data[key]
})
リファレンスアドレス