总结
Vue2采用数据劫持结合发布订阅模式(PubSub 模式)的方式,通过 Object.defineProperty 来劫持各个属性的 setter、getter,在数据变动时发布消息给订阅者,触发相应的监听回调。 当把一个普通 Javascript 对象传给 Vue 时,Vue 将遍历它的属性,用 Object.defineProperty 将它们转为 getter/setter。用户看不到 getter/setter,但是在内部它们让 Vue 追踪依赖,在属性被访问和修改时通知变化。 Vue 的数据双向绑定整合了 Observer,Compile 和 Watcher 三者,通过 Observer 来监听自己的 model 的数据变化,通过 Compile 来解析编译模板指令,最终利用 Watcher 搭起 Observer 和 Compile 之间的通信桥梁,达到数据变化-视图更新,视图交互变化(例如 input 操作)-数据 model 变更的双向绑定效果。
但是Vue3放弃了 Object.defineProperty ,使用 ES6 原生的 Proxy。
Object.defineProperty(obj, propertyName, descriptor)
该方法用于定义某个属性的描述符
const user = {
name: '柒柒',
age: 17
};
Object.defineProperty(obj, 'name', {
value: '邓予柒', // 将其值进行修改
enumerable: false, // 让该属性不能被遍历
writable: false // 让该属性无法被重新赋值
})
getter 和 setter
属性描述符中有两个特殊的配置,分别为get
和set
,通过它们,可以把属性的取值和赋值变为方法调用
const obj = {};
Object.defineProperty(obj, 'a', {
get(){ // 读取属性a时,得到的是该方法的返回值
return 1;
},
set(val){ // 设置属性a时,会把值传入val,调用该方法
console.log(val)
}
})
console.log(obj.a); // 输出:1
obj.a = 3; // 输出:3
console.log(obj.a); // 输出:1