<template>
<div>
<div v-for="item in list2">{{item.name}}{{item.title}}</div>
<button @click="change">按钮</button>
</div></template><script type="text/ecmascript-6">export default {
data() { return { list1: { name: "John", id: 1 }, list2: [],
};
},
created() { this.obj = this.list1 //Object.assign(this.obj,{title:'123'}) //←直接绑定到obj上不会给title绑定get和set所以点击按钮也不会更新视图
//↓创建一个新的对象title就能成功绑定get和set~这是什么原理,求解惑
this.obj = Object.assign({},this.obj,{title:'123'})
console.log(this.obj); this.list2.push(this.obj) console.log(this.list2);
}, methods: {
change(){ this.list2[0].title='harry'
}
}
};</script>我的理解是vue会直接给新声明对象的所有属性自动绑定set和get~Object.assign把对象合并到新对象上,相当于把合并对象的所有属性重新声明到新对象上所以自动绑了get和set,不知道有没有理解错~
2 回答
ITMISS
TA贡献1871条经验 获得超8个赞
这个和vue的observe实现源码有关了,会观察对象有没有__ob__属性,如果有就不会再去new Observer,如果没有就会去new Observer, Object.assig不会拷贝__ob__(不可枚举的)这个属性
相关vue源码如下
/**
* Attempt to create an observer instance for a value,
* returns the new observer if successfully observed,
* or the existing observer if the value already has one.
*/
function observe(value, asRootData) { if (!isObject(value) || value instanceof VNode) { return
} var ob; // 检查是否有__ob__属性
if (hasOwn(value, '__ob__') && value.__ob__ instanceof Observer) {
ob = value.__ob__;
} else if (
shouldObserve &&
!isServerRendering() &&
(Array.isArray(value) || isPlainObject(value)) &&
Object.isExtensible(value) &&
!value._isVue
) {
ob = new Observer(value);
} if (asRootData && ob) {
ob.vmCount++;
} return ob
}/**
* Observer class that is attached to each observed
* object. Once attached, the observer converts the target
* object's property keys into getter/setters that
* collect dependencies and dispatch updates.
*/
var Observer = function Observer(value) { this.value = value; this.dep = new Dep(); this.vmCount = 0; // 添加__ob__属性
def(value, '__ob__', this); if (Array.isArray(value)) { if (hasProto) {
protoAugment(value, arrayMethods);
} else {
copyAugment(value, arrayMethods, arrayKeys);
} this.observeArray(value);
} else { this.walk(value);
}
};添加回答
举报
0/150
提交
取消
