私はオブジェクトprops
を子コンポーネントに渡す必要がある場合があります。Vue2の条件付き小道
最初は、コンポーネント内にフォームとテーブルが含まれていました。このフォームは入力を受け取り、非同期要求が実行され、ユーザーが選択を行うためにテーブルがレンダリングされます。ユーザーはボタンを押してテーブルを隠し、フォームを元に戻してパラメータを再入力することができます。フォームの内容は親の状態に依存していたため、最後の検索パラメータはまだフォームになっていました。
私は、フォームと親のテーブルのサブコンポーネントの両方を作成するためにコンポーネントをリファクタリングするときに問題が発生しました。これでフォームは$emit
の親イベントになり、非同期操作が実行され、結果はprops
としてテーブルに渡されます。これは正常に機能しましたが、ユーザーが「フォームに戻る」ボタンを押すと、フォームが再描画され、状態が初期値にリセットされます。
フォームの内容を親に保存して、props
という形式に戻してみましたが、最初に値を設定するという問題が発生しました。私は直接小道具を変異させたくなかったので、私はこのアプローチを試みた:FormComponent.vue
<template>
<!--Some form fields here, bound to data(){}, ommitted for brevity-->
</template>
<script>
export default{
props:['initialValues'],
data(){
return{
//Original structure
/*selectedAddress:{
address1: '',
address2: '',
address3: '',
country: ''
}*/
selectedAddress: JSON.parse(JSON.stringify(this.initialValues)) //Object.assign({}, this.initialValues) //tried both of these for deep copy
}
}
}
</script>
FormContainer.vue
<template>
<div v-if="formShown">
<form-component :initialValues="formValues" @formSubmitted="displayResults"></form-component>
</div>
<div v-if="tableShown">
<table-component :results="fetchedResults" @returnToForm="returnToForm"></table-component>
</div>
</template>
<script>
export default {
data(){
return{
formShown: true,
tableShown: false,
formValues:{
address1: '',
address2: '',
address3: '',
country: ''
},
fetchedResults: []
}
},
methods:{
async displayResults(){
this.fetchedResults = await someAsynchronousCall();
this.formShown = false;
this.tableShown = true;
},
returnToForm(){
this.tableShown = false;
this.formShown = true;
}
}
}
</script>
をこれで問題となったときに、コンポーネントいます最初に作成されたのは、空のオブジェクト(または空のプロパティのみを持つオブジェクト)であり、データプロパティがundefined
として初期化されていることを意味します。
私は、このように、小道具の値または空の文字列とデータオブジェクトを初期化するために、三元を使用してみました:
data(){
return{
selectedAddress: {
address1: this.initialValues.address1 ? this.initialValues.address1 :'',
address2: this.initialValues.address2 ? this.initialValues.address2 :'',
address3: this.initialValues.address3 ? this.initialValues.address3 :'',
country:this.initialValues.country ? this.initialValues.country :''
}
}
},
しかし、これはselectedAddress
がインスタンスで定義されていないというエラーがスローされますが、レンダリング中に参照されます。私はこれが、三元を使って小道具を初期化するのが間違っていることを推測しています。
mounted(){
if(!this.initialValues || _.isEmpty(this.initialValues)){
Logger.info(`no props passed, no setup needed`);
return;
}
if(this.initalValues.address1){
Logger.info(`setting address 1`);
this.selectedAddress.address1 = this.initalValues.address1;
}
if(this.initialValues.address2){
Logger.info(`setting address 2`);
this.selectedAddress.address2 = this.initalValues.address2;
}
if(this.initialValues.address3){
Logger.info(`setting address 3`);
this.selectedAddress.address3 = this.initalValues.address2;
}
if(this.initialValues.country){
Logger.info(`setting country`);
this.selectedAddress.country = this.initalValues.country;
}
}
これは、フォームの最初の実行のために動作しますが、this.initialValues
は常にundefined
ときです:
私は、このように、mounted(){}
ライフサイクルフックに小道具をチェックし、そこにデータプロパティを設定しようとしましたコンポーネントがマウントされます。私はコンポーネントの状態を調べて、initialValues
が存在することを発見しました。ちょうどmounted
ライフサイクルフックの間ではありません。このアプローチはとにかく「ハッキー」を感じました。
ここからどこに行くのかはわかりません。私はフォームデータをストアにコミットし、フォームが再ロードされた場合に再度取得できますが、親がマウントされている間だけ存在する必要があるものをコミットするような気がしません。
誰でも私にこれを達成するためのより多くの方法を教えてもらえますか?
私は現在Vuexを使用していますが、私が実装した回避策はVuexを使用しています。私の問題は、ユーザーがフォームをリセットしたときにフォームコンテナの親がDOMから削除されたときなど、適切な時にストアからデータを削除するための正しいアクションをディスパッチすることを忘れないようにする必要があるということですユーザーが親の中からフォームをリセットしたときに、フォーム内からフォームを削除することができます。これは、これがフォームの不正な初期状態を持つ簡単な方法であることがわかります。 – JavaTheNutt
計算されたプロパティを使用すると、フォームがまだ開いている間に、何らかの形で、 'initalValues'の内容が親で変更された場合、フォームフィールドの値自体が変更されますか?私は 'Object.assign()'を使ってフォームの値と親から渡されたデータとの間のリンクを解除しようとしていましたが、これは 'computed(){}'で使われている場合でもそうでしょうか? – JavaTheNutt
私はちょうどフォームを隠すという考え方に似ていますが、複雑さを軽減し、DOMの周りにぶら下がっているのは巨大なコンポーネントではありません。未使用の要素を非表示にするのではなく、削除することは通常受け入れられていますが、この場合は除外を行うことがあります。 – JavaTheNutt