这段时间在看vue的双向绑定原理,知道了vue的核心三大件:Observer, Complie, Watcher。
Observer用于监听属性的变化,如有变动就通知 Watcher。
Compile负责解析元素节点的指令,如v-if,v-bind之类, 进行数据和回调函数的绑定。
Watcher收到属性变动的通知,就触发对应属性的回调函数,更新视图。
在学习 Watcher 的实现时,发现用的是发布订阅模式,也称观察者模式。
其实我们从开始用 js/jQuery 监听事件开始,就已经在用发布订阅模式了。
例如 DOM 中的 addEventListener, jquery 的 on 绑定事件。
发布订阅模式,比较好理解。举几个例子:
电饭煲煮饭,电饭煲本身并不知道要在什么时候跳到保温,它就只能等通知,等到饭烧好了,电饭煲的某个控制器就发出一个通知, 喂喂喂,饭熟了,不要再煮了。OK,电饭煲的电源控制器收到通知了,好,我跳保温。
dianfanbao.addEvent('煮好了', function(){jumpTo('保温');
});
复制代码
生活中的烧水啊,空调定时啊,你要买房子需要等开盘消息呀,都可以算是发布订阅模式吧。
发布订阅的核心思想就是维护一个对象,对象里面存放着各种事件的数组,根据不同的事件遍历不同的数组,执行回调。
一言不合上代码
class EventModel {constructor() {this.events = {};}on(eventType, fn) {if (!this.events[eventType]) {this.events[eventType] = [];}this.events[eventType].push(fn);}trigger(eventType, ...args) {let eventCallbacks = this.events[eventType];if (Array.isArray(eventCallbacks)) {eventCallbacks.forEach( fn => fn.apply(this, args) );}}off(eventType, fn) {let eventCallbacks = this.events[eventType];if ( !fn ) {eventCallbacks.length = 0;}let idx = eventCallbacks.indexOf(fn);if (idx !== -1) {eventCallbacks.splice(idx, 1);}}
}
复制代码
测试
let event = new EventModel();let f = x => alert(x);
event.on('click', f);
event.trigger('click', 2); //alert(2);
event.off('click', f);
复制代码
这周末比较忙,就先简单记录一下,争取早日搞懂双向绑定原理,分享出来给有需要的人。