vue之MVVM雙向繫結原理
阿新 • • 發佈:2021-06-23
class Watcher { constructor(obj, key, cb) { // Watcher建構函式,先把當前watcher放到一個地方 window.curWatcher = this // 觸發getter,在getter裡就可以將先前放好的watcher拿出來放到其dep中 this.value = obj[key] // window.curWatcher = null this.cb = cb } update(oldVal, val) { this.cb(oldVal, val) } } class Dep { constructor() { this.subs = [] } notify(oldVal, val) { if (this.subs === []) return this.subs.forEach(item => { item.update(oldVal, val) }) } } //建立Observer遞迴呼叫這個函式, function defineReactive(obj, key, val) { let dep = new Dep() Object.defineProperty(obj, key, { enumerable: true, configurable: true, get: () => { // 收集watcher if (window.curWatcher !== undefined) { dep.subs.push(window.curWatcher) } return val }, set: (newVal) => { if (val === newVal) return // 通知watcher去呼叫回撥函式更新檢視 dep.notify(val, newVal) val = newVal } }) } function compiler() { //模板編譯,建立watcher,傳遞更新檢視的回撥函式 //訂閱 new Watcher(data, path, () => {}) } defineReactive(obj, path, '') compiler()