Vue中的观察者模式
一、什么是观察者模式
当一个对象中的数据被多个对象所依赖,并且当被依赖发生变化的时候,会通知所有的依赖项。我们称这种模式为观察模式,被依赖的对象我们称之为目标,依赖项我们称之为观察者。
二、观察者模式与订阅发布者模式的区别
1、观察者模式
在观察者模式中,目标与观察者是直接通信的。他们知道彼此的存在,当被依赖项发生变化时,是目标直接通知观察者的。
2、订阅发布者模式
而在订阅与发布者模式中,订阅者与发布者之间是通过统一的调度中心来实现数据的通信(比如兄弟组件通信中的eventBus就是信息的中间传递着),他们彼此并不知道对方的存在。当发布者发布信息的时候,是先传到统一的调度中心,再由调度中心统一传递给所有订阅者。
三、观察者模式的原理
我们可以创建一个目标对象(Dep)及若干个观察者对象(Watcher)。
1、目标对象
在目标对象中,我们可以定义一个数组(watcherList),用于存储目标的观察者对象。并且还可以在目标对象中定义2个方法:
第一个方法:add(){},在有其他对象依赖这个目标对象的时候触发,用于向观察者数组中添加观察者对象。第二个方法:notify(){},在目标对象的数据发生变化的时候被触发,用于通知观察者,其内部是遍历观察者数组中的每一个对象,并调用这些观察者对象中的update()方法,将变化后的数据传递给这些观察者。
// 创建一个Dep类(目标类)
class Dep {
constructor(name) {
this.name = name;
this.watcherList = []; //用来登记哪些人要买衣服
}
add(watcher) {
this.watcherList.push(watcher);
}
notify() {
this.watcherList.forEach((item) => {
item.update();
});
}
}
//创建一个被观察者的实例
const dep = new Dep("宝宝");
2、观察者对象
而在观察者对象中,我们同样可以定义一个方法update(),这个方法是由目标对象在notify()中遍历调用的,用于将变更后的数据传递给观察者。
// 创建一个Watcher类(观察者类)
class Watcher {
constructor(name) {
this.name = name;
}
update() {
console.log(this.name + "被通知到了");
}
}
//创建二个观察者
const father = new Watcher("爸爸");
const mother = new Watcher("妈妈");
//把这二个观察者添加到被观察者的列表中
dep.add(father);
dep.add(mother);
//当宝宝被观察者有需求的时候,就去通知所有的观察者
dep.notify();
四、观察者模式的应用
在Vue中,数据驱动页面渲染(数据的双向绑定)就是利用数据响应模式+观察者模式来实现的。当页面中的数据发生变化的的时候,通过数据劫持,将变更的数据信息通知给Dep,再使用观察者模式,通知每个组件的Watcher实例,从而驱动页面的更新,实现数据驱动页面渲染(数据的双向绑定)。Vue的数据响应式原理