Vue,手写一个简单的数据响应式,ref、effect(18)

0 阅读1分钟
/**
 * 简单实现响应式(ref、effect)
 */

class RefImpl {
  _value
  subs = new Set<() => void>()
  constructor(value: any) {
    this._value = value
  }

  get value() {
    // 收集依赖
    if (activeSub) {
      /**
       * 建立 ref 和 activeSub 之间的联系
       */
      this.subs.add(activeSub)
    }
    return this._value
  }

  set value(newValue) {
    this._value = newValue
    this.subs.forEach((fn) => fn())
  }
}

function ref(value: any) {
  return new RefImpl(value)
}

// 相当于拔高作用域(源码里常用)
let activeSub: undefined | (() => void)

function effect(fn: () => void) {
  activeSub = fn
  // 这样在运行完函数前,收集依赖就能拿到该fn
  fn()
  activeSub = undefined
}

const count = ref(0)

effect(() => {
  console.log('count value ==>> ', count.value)
})

setTimeout(() => {
  count.value++
}, 500)