Open AnnVoV opened 6 years ago
有个疑问, Object.assign(this.form, newData) 的情况下,此时newVal是新值,而value是在getter.call(obj)得到的,应该是旧值,因为set还没完成。此时,如果新值不等于旧值,那就不会return啊?
我懂了,您说的是form这个属性,而不是form中的title属性。对于Object.assign(this.form, newData),this.form的地址并没有变,所以newVal === value不会触发更新,对于Object.assign({}, this.form, newData),产生了新的对象赋值给this.form, 着改变了form的地址,所以newVal !== value可以触发更新。
是的 是那个意思
=_= 所以即使只是想要修改子属性,就必须创建一个新的对象吗?但是我在自定义的class中,使用 Object.assign 是可以正确调用属性的 set 的
t1 = {
_a:1,
set a(value){
console.log('set a')
this._a = value;
},
get a(){
console.log('set a')
return this._a;
}
}
Object.assign(t1, { a: 1 })
控制台使用,可以看到属性 set 是可以被成功调用的,但是对 vue 响应对象却无效,无法理解。
vue初始化的时候会对t1进行Observe,把里面现有
的属性都变成响应式的,现在你Object.assign(t1, { a: 1 })
这个a属性是一个新的属性,之前没有被Observe过,所以不会生效。
简化一下问题:
new Vue({
data() {
return {
_a:1
}
}
})
解决方案有:
this.t1 = Object.assign({}, t1, {a:1})
assign此时会返回一个新对象,把它赋值给t1,实际上是this.data.t1=Object.assign({}, t1, {a:1})
, 因为data同样在初始化的时候Observe过t1属性,而此时t1的引用变了,所以会触发更新
this.$set(this.t1, 'a', 1)
这一步不仅给t1添加了一个a属性,同时还Observe了这个属性
一开始就让vue去Observe这个a属性
t1 = {
_a:1,
a: 0
}
😅 发现我看错了,原来工作是正常。我的使用场景正是已经初始化过了,通过 Object.assign 同时修改多个属性而已。
前言
之前一直没有很注意vue源码中的proxy方法,最近遇到一个问题,发现了一些忽略的细节。背景如下:
背景
一般我们都会在mounted钩子里面去写一些通过异步接口获取数据的方法,比如下面,发现Object.assign 下面两种写法结果不一样
原因
因为在set里面有这样一个判断
因为
Object.assign(this.form, newData)
是在原对象上修改的新的值,所以this.form 在被修改值的时候,会进入其setter,且此时newVal === value
所以会return 也就是新的值没有进入observe(newVal)方法 而Object.assign({}, this.form, newData) 相当于创建了一个新对象,此时newVal === value 就不成立了,所以会进入observe(newVal)的方法