這段時間在看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);
復制代碼
這周末比較忙,就先簡單記錄一下,爭取早日搞懂雙向綁定原理,分享出來給有需要的人。