想要搞定响应式原理必须搞定两个问题:
1、当Vue里面的data数据改变时,Vue内部是如何监听数据的改变?
Object.defineProperty里的set与get方法 -> 监听对象属性的改变
let obj = { // 定义的obj对象
name: '涂涂',
age: 18,
gender: 'male'
};
Object.keys(obj).forEach(key => { // 遍历得到obj对象的每个key
let value = obj[key]; // 取出key对应的键值
Object.defineProperty(obj, key, { // 使用Object.defineProperty来对obj对象里面的属性实施监听
set(newValue) { // 只要属性名一改变,则调动set方法
console.log('set');
value = newValue;
},
get() { // 只要属性名一调用,则调动get方法
console.log('get');
return value;
}
})
});
2、当数据发生改变后,Vue是如何知道需要通知哪些地方进行数据更新呢?
发布者订阅者模式
let obj = {
name: '涂涂',
age: 18,
gender: 'male'
};
class Dependence { // 发布者
constructor() {
this.subscribes =[]; // 记录订阅者
}
addSub(watcher) { // 给发布者添加订阅者
this.subscribes.push(watcher)
}
notify() { // 当数据发生改变时调用notify方法,通知订阅者数据已改变
this.subscribes.forEach(item => {
item.undate();
})
}
}
class Watcher { // 订阅者
constructor(value) { // 订阅者本身的讯息
this.value= value;
}
undate() { // 当数据改变时,订阅者的具体操作
console.log('属性值: ' + this.value + ' 发生update');
}
}
Object.keys(obj).forEach(key => {
let value = obj[key];
const dep = new Dependence(); // 实例化发布者,注意这里必须是为每个属性都添加一个发布者,当那个属性对应的发布者发生改变的时候对应的订阅者就会收到讯号
dep.addSub(new Watcher(value)); // 添加订阅者
Object.defineProperty(obj, key, {
set(newValue) {
value = newValue;
dep.notify() // 当数据改变时,发布者调用notify方法告诉订阅者数据已改变
},
get() {
return value;
}
})
});
开始时:
数据改变时:
要注意这里的一个属性对应一个发布者
本文只用于个人学习与记录