第17题 实现vue reactive原理

    // Dep module
    class Dep {
      static stack = []
      static target = null
      deps = null
      
      constructor() {
        this.deps = new Set()
      }
    
      depend() {
        if (Dep.target) {
          this.deps.add(Dep.target)
        }
      }
    
      notify() {
        this.deps.forEach(w => w.update())
      }
    
      static pushTarget(t) {
        if (this.target) {
          this.stack.push(this.target)
        }
        this.target = t
      }
    
      static popTarget() {
        this.target = this.stack.pop()
      }
    }
    
    // reactive
    function reactive(o) {
      if (o && typeof o === 'object') {
        Object.keys(o).forEach(k => {
          defineReactive(o, k, o[k])
        })
      }
      return o
    }
    
    function defineReactive(obj, k, val) {
      let dep = new Dep()
      Object.defineProperty(obj, k, {
        get() {
          dep.depend()
          return val
        },
        set(newVal) {
          val = newVal
          dep.notify()
        }
      })
      if (val && typeof val === 'object') {
        reactive(val)
      }
    }
    
    // watcher
    class Watcher {
      constructor(effect) {
        this.effect = effect
        this.update()
      }
    
      update() {
        Dep.pushTarget(this)
        this.value = this.effect()
        Dep.popTarget()
        return this.value
      }
    }
    
    // 测试代码
    const data = reactive({
      msg: 'aaa'
    })
    
    new Watcher(() => {
      console.log('===> effect', data.msg);
    })
    
    setTimeout(() => {
      data.msg = 'hello'
    }, 1000)
Last Updated:
Contributors: leeguooooo