我有一個用例,我可能需要將一個對象props
作爲道具傳遞給子組件。Vue2中的條件道具
最初,我有一個組件中包含的表單和表。該表單將接受輸入,將執行一個異步請求,併爲該用戶提供該表以供選擇。然後用戶可以按下一個按鈕並隱藏表格,並將表格帶回來,以便重新輸入參數。由於表單的內容取決於其父項的狀態,因此最後的搜索參數仍處於表單中。
當我重構組件以創建父窗體和表的子組件時,就會出現此問題。現在表單將$emit
事件發送給它的父項,它將執行異步操作並將結果作爲props
傳遞給表。這工作得很好,但是當用戶點擊「返回到表單」按鈕時,表單被重新呈現,從而將其狀態重置爲初始值。
我試圖將表單的內容存儲在父級中,並將其傳回到表單props
,但導致初始設置值的問題。我不想直接發生變異的道具,所以我嘗試這個辦法:
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>
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>
這樣做的問題是,當組件最初創建時,它正在傳遞一個空對象(或者更確切地說是一個只有空屬性的對象,我假設它們是相同的東西),這意味着我的數據屬性被初始化爲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(){}
生命週期掛鉤,以檢查道具,並設置數據屬性有,像這樣:
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
當組件被安裝。我檢查了組件狀態,發現initialValues
確實存在,只是在mounted
生命週期中沒有掛鉤。無論如何,這種方法都感覺到'黑客'。
我不確定該從哪裏出發。我可以將表單數據提交給商店,如果表單重新裝入,可以重新獲取表單數據,但是我不想提交僅在父表單掛載時存在的東西纔是正確的方法。
任何人都可以引導我更多Vue的方式來實現這一目標嗎?
我目前使用的是Vuex,我實現的解決方法是使用Vuex。我的問題是,我必須確保記得在所有適當的時間,即當表單容器的父級從DOM中刪除時,當用戶重置表單時,記錄分派正確的操作以從商店中刪除數據從表單中,當用戶從其父母等重置表單時,我可以看到這是一種簡單的方法,在表單中有一個不正確的初始狀態。 – JavaTheNutt
使用計算屬性並不意味着如果在表單仍處於打開狀態時,「initalValues」的內容發生了變化,那麼表單字段值本身會發生變化?我試圖使用Object.assign()來打破錶單值和從父類傳遞的數據之間的鏈接,如果它在'computed(){}'中使用,情況仍然如此嗎? – JavaTheNutt
我確實喜歡隱藏表單的想法,它會降低複雜性,並且它不是掛在DOM周圍的一個巨大組件。我知道通常會接受的做法是移除未使用的元素,而不是隱藏它們,但在這種情況下,我可能會做出豁免 – JavaTheNutt