观察者模式核心:
观察者(Watcher):每个观察者都必须有一个Update()方法。事件发生的时候,触发并执行观察者的Update()方法。类似于发布/订阅者中的订阅者
目标( Dependency 依赖):类似于发布/订阅者中的发布者
- subs数组:存储所有的观察者
- addSub():添加观察者
- notify():当事件发生时,调用所有观察者的update(),达到发布目的。
在Vue 中应用就是视图的实时更新
- 每个组件实例都对应一个 watcher 实例,它会在组件渲染的过程中把“接触”过的数据 property 记录为依赖。之后当依赖项的 setter 触发时,会通知 watcher,从而使它关联的组件重新渲染。
- Vue组件的data并非所有属性都会收集为依赖,而是被模板引用的属性才会收集为依赖
- 当渲染模板时,msg将会触发getter函数,即收集依赖的地点就是在getter中。
- 在某种情况下对msg进行了重新赋值,那么将会触发setter函数,既然msg改变了,那么视图就要更新了,即通知更新的地点在setter中
- 如何通知更新?在setter中使用dep的notify方法通知Watcher,即调用观察者的update方法,使得组件重新渲染。
<!-- 观察者模式 -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>观察者模式</title>
</head>
<body>
<script>
class Dep{
constructor() {
this.subs = []
}
addSub(sub) {
// 所有观察者都应有update
if(sub&&sub.update){
this.subs.push(sub)
}
}
notify() {
this.subs.forEach(item =>{
item.update(item)
})
}
}
//观察者类
class Watcher{
update(item){
console.log(item)
console.log('update')
}
}
let watcher1 = new Watcher();
let watcher2 = new Watcher();
let dep = new Dep();
dep.addSub(watcher1);
dep.addSub(watcher2);
setTimeout(()=>{
dep.notify();
},3000)
</script>
</body>
</html>