- 父组件将 数据(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>
`
})