- 父組件將 數據(Object) 傳遞到子組件
- 子組件直接使用這個對象,並修改這個對象,會影響到父組件中的對象;
- 子組件通過data,將父組件傳遞過來的對象轉換成本地數據,修改對象依然會影響到父級數據,因爲對象是引用數據類型,如下圖所示;
props: ['obj'],
data(){
return {
iObj: this.obj
}
}
所以就需要讓本地對象跟父級對象徹底斷絕聯繫;
有以下兩種方法:
1. 深拷貝
props: ['obj'],
data(){
return {
iObj: JSON.parse(JSON.stringify(this.obj))
}
}
2. 擴展運算符 ...
props: ['obj'],
data(){
return {
iObj: {
...this.obj
}
}
}
子組件修改數據之後,父組件的數據也需要隨之修改,該怎麼處理呢?
那就是監聽子組件的數據變化,通過 $emit
通知父組件更新數據;
要知道,普通的監聽對於對象來說是無效的,所以在子組件中 監聽對象數據的變化 方法如下:
// 需要注意的是, 如下傳遞給父組件的對象也進行了一次轉換(...this.iObj),徹底避免掉引用關係
watch: {
iObj: {
handler(newVal){
this.$emit('upDate', {...this.iObj})
},
deep: true
}
},
所以一個對象,從傳入子組件,到子組件更新後將新數據傳遞到父組件的過程如下:
Vue.component('test', {
props: ['obj'],
// 通過擴展運算符,將父組件傳遞過來的對象徹底轉換成本地數據
data() {
return {
iObj: {
...this.obj
}
}
},
// 監聽本地對象的變化,更新到父組件
watch: {
iObj: {
handler(newVal){
this.$emit('upDate', {...this.iObj})
},
deep: true
}
},
template: `
<div>
<p>子組件:{{iObj}}</p>
<input type="text" v-model="iObj.name" />
</div>
`
});
new Vue({
el: "#app",
data() {
return {
obj: {name: "任重道遠"}
}
},
methods: {
update(newVal){
this.obj = newVal;
}
},
template: `
<div>
<h2>父組件: {{obj}}</h2>
<test :obj="obj" @upDate="update"/>
</div>
`
})