一、問題產生背景:
向子組件傳一個動態生成的數組,數組中包含着多級的對象數組
// 父組件聲明的數組對象 slots: any = [ { flex: 1, values: [], className: 'pro_slot', textAlign: 'center' }, { divider: true, content: '-', className: '' }, { flex: 1, values: [], className: 'city_slot', textAlign: 'center' }, { divider: true, content: '-', className: '' }, { flex: 1, values: [], className: 'aera_slot', textAlign: 'center' } ];
// 父組件內調用請求數據更換slots部分屬性值 async initAreaData(id?: any) { const pro_res = await getCityData(id); const pro_data = pro_res.data.data; this.$set(this.slots[0], 'values', pro_data); const city_res = await getCityData(pro_data[0].region_id); const city_data = city_res.data.data; this.$set(this.slots[2], 'values', city_data); const area_res = await getCityData(city_data[0].region_id); const area_data = area_res.data.data; this.$set(this.slots[4], 'values', area_data); }
// 傳值給子組件 <areapicker2 :slots='slots' ></areapicker2>
// 子組件接收 props: { slots: { type: Array }, }
// 子組件頁面使用 <ul v-if='slot.values' :class="['slots',{select_slots: slot.values}]" :id="'slot' + slotIndex" v-for="(slot, slotIndex) in slots" :key="slotIndex"> <li v-for="(itemValue, index) in slot.values" :key="index"> {{itemValue.region_name}} </li> </ul>
// 子組件初始化時打印傳過來的slots數組對象及其屬性值 mounted () {
console.log('this.slots',this.slots)
console.log('this.slots[0]', this.slots[0])
console.log('this.slots[0].values', this.slots[0].values)
}
打印結果如下:
發現頁面是正常渲染的所有數據,但是在js中,獲取數組對象中更深層次的數組值時,發現this.slots[0].values拿到的是原先的父組件的slots數組中默認的值,而不是有34個內容的Array。
二、嘗試解決
(1)加上定時器,發現可以獲取得到,取到后再執行相關邏輯代碼,缺點是延遲時間不好把控,太短基本還是取不到值,太長又可能有其他問題,需要結合實際情況優化;或者使用setInterval,再獲取到之后記得立馬清除clearInterval定時器
mounted () { console.log('this.slots',this.slots) console.log('this.slots[0]', this.slots[0]) setTimeout(()=>{
console.log('this.slots[0].values',this.slots[0].values)
console.log('this.slots[2].values',this.slots[2].values)
console.log('this.slots[4].values',this.slots[4].values)
},2000)
}
打印結果如下:
(2)使用深度監聽,取到值后再執行相關邏輯代碼,缺點是看情況存在多次變化多次執行監聽函數的情況,直到最后一次才能全部獲取到正確的值,像前面通過三次異步請求改變了slots三處values屬性值,監聽函數觸發了三次,第三次才能獲取到全部的值
// 子組件深度監聽slots watch: { slots: { handler: function (newval, oldval) { console.log('this.slots', this.slots) console.log('this.slots[0].values',this.slots[0].values) console.log('this.slots[2].values',this.slots[2].values) console.log('this.slots[4].values',this.slots[4].values) }, deep: true } },
打印結果如下:
(3)使用vuex來通信