if (this.subs[eventType]) {
this.subs[eventType].forEach(handler => {
handler()
})
}
}
}
// 测试
var bus = new EventEmitter()
// 注册事件
bus.$on(‘click’, function () {
console.log(‘click’)
})
bus.$on(‘click’, function () {
console.log(‘click1’)
})
// 触发事件
bus.$emit(‘click’)
观察者
-
观察者(订阅者)— Watcher
-
update():当事件发生时,具体要做的事情
-
目标(发布者)— Dep
-
subs 数组:存储所有的观察者
-
addSub():添加观察者
-
notify():当事件发生,调用所有观察者的 update() 方法
-
没有事件中心
// 目标(发布者)
// Dependency
class Dep {
constructor () {
// 存储所有的观察者
this.subs = []
}
// 添加观察者
addSub (sub) {
if (sub && sub.update) {
this.subs.push(sub)
}
}
// 通知所有观察者
notify () {
this.subs.forEach(sub => {
sub.update()
})
}
}
// 观察者(订阅者)
class Watcher {
update () {
console.log(‘update’)
}
}
// 测试
let dep = new Dep()
let watcher = new Watcher()
dep.addSub(watcher)
dep.notify()
总结
-
观察者模式 是由具体目标调度,比如当事件触发,Dep 就回去调用观察者的方法,所以观察者模式的订阅者与发布者之间是存在依赖的
-
发布/订阅模式 是由统一调度中心调用,因此发布者和订阅者不需要知道对方的存在
整体分析
-
Vue 基本结构
-
打印 Vue 实例观察
-
整体结构
-
Vue
-
把 data 中的成员注入到 Vue 实例,并且把 data 中的成员转成 getter/setter
-
Observer
-
能够把数据对象的所有属性进行监听,如有变动可拿到最新值并通知 Dep
-
Compiler
-
解析每个元素中的指令/插值表达式,并替换成相应的数据
-
Dep
-
添加观察者(watcher),当数据变化通知所有观察者
-
Watcher
-
数据变化更新视图
Vue 类
-
功能
-
接收初始化的参数(选项)
-
把 data 中的属性注入到 Vue 实例,转换成 getter/setter
-
调用 observer 监听 data 中所有属性的变化
-
调用 compiler 解析指令/插值表达式
-
结构
-
$options
-
$el