1.父组件
<template>
<div class="parent">
<child info='obj'></child>
</div>
</template>
<script>
import child from './child'
export default {
components: {
child
},
data () {
return {
obj: {
key1: '',
key2: ''
}
}
},
methodes: {
changeObj () {
this.obj.c = '123'
}
}
}
</script>
2.子组件
<template>
<ul class="child">
<li :key='item' v-for="item in obj">{{item}}</li>
</ul>
</template>
<script>
export default {
props: {
type: Object,
default: () => {}
}
}
</script>
当调用父组件的changeObj方法时,发现在child组件中并没有更新视图,查阅vue的官方网站,给出的解释受现代 JavaScript 的限制 (而且 Object.observe 也已经被废弃),Vue无法检测到对象属性的添加或删除。由于 Vue 会在初始化实例时对属性执行 getter/setter 转化,所以属性必须在 data 对象上存在才能让 Vue 将它转换为响应式的。同时也给了[解决方案](https://cn.vuejs.org/v2/guide/reactivity.html#ad)
解决方案
- Vue 不允许动态添加根级别的响应式属性。但是,可以使用this.set方法进行属性设置。
changeObj () {
this.$set(this.obj, 'c', '123')
}
2.需要为已有对象赋值多个新属性,比如使用 Object.assign() 或 _.extend()。但是,这样添加到对象上的新属性不会触发更新。在这种情况下,你应该用原对象与要混合进去的对象的属性一起创建一个新的对象
Object.assign() 方法用于将所有可枚举属性的值从一个或多个源对象复制到目标对象。它将返回目标对象。
// target 目标对象。
// sources 源对象。
// Object.assign()拷贝的是属性值。假如源对象的属性值是一个对象的引用,那么它也只指向那个引用。
Object.assign(target, ...sources)
this.someObject =Object.assign({},this.someObject, {a:1,b:2})