vue响应式数据-修改对象的属性值,视图不更新
vue设置响应式数据
·
bug复现
在代码中给一个对象,新增多个属性并赋值,然后在另一个方法中修改对象其中一个属性的值,发现数据改变,页面视图并没有更新
data: {
return() {
obj: {},
}
},
methods: {
fun1() {
this.obj.a = 1;
this.obj.b = 2;
},
fun2() {
this.obj.a = 3;
},
}
原因
翻了vue官方文档:
vue 无法检测 property 的添加或移除。由于 Vue 会在初始化实例时对 property 执行 getter/setter转化,所以 property 必须在 data 对象上存在才能让 Vue 将它转换为响应式的。对于已经创建的实例,Vue允许动态添加根级别的响应式 property。
看到这就大概清楚原因了,上面obj对象的属性a和b没有在data中定义,那a和b就不是响应式数据,后面修改这两个属性的值,自然也无法实时更新到视图。
怎么在console中判断是不是响应式数据
下面这张图可以看到有a和b都有get
set
属性,则这两个属性都为响应式数据,如果没有get set,则为非响应式
怎样才能设置为响应式数据
(1)像上面提到的,在data中定义了的就是响应式数据,如:
data: {
return() {
obj: {
a: '',
b: '',
},
}
},
// a和b为响应式数据
(2)如果一开始并不知道这个对象上会有哪些属性,怎么办?
- 使用vue提供的
vm.$set()
方法,给对象增加属性值
// 这样obj的b属性就为响应式数据了
this.$set(this.obj,'b',2)
- 如果要为对象赋值多个属性,则可以用
Object.assign()
// 用原对象与要混合进去的对象的 property 一起创建一个新的对象。
this.obj = Object.assign({}, this.obj, { a: 1, b: 2 })
- 还有一种方法,使用es6的对象扩展运算符
this.obj.a = 1;
this.obj.b = 2;
this.obj = {...this.obj}; // 这里扩展运算符实质是深拷贝对象的属性
(3)如果是数组,即使在data中定义了,也无法检测到变动
参考vue官方文档:
Vue 不能检测以下数组的变动: 当你利用索引直接设置一个数组项时,
例如:vm.items[indexOfItem] = newValue
当你修改数组的长度时,例如:vm.items.length = newLength
以下三种方法设置数组为响应式数据:
$set()
方法
this.$set(this.arr, 0, 'a'); // 设置数组第一个元素为arr = ['a']
splice()
this.arr.splice(0, 1, 'a');
- 数组扩展运算符
this.arr[0] = 'a';
this.arr = [...this.arr];
更多推荐
已为社区贡献2条内容
所有评论(0)