1. 程式人生 > 其它 >vue之MVVM雙向繫結原理

vue之MVVM雙向繫結原理

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()