Vue3绑定

290 阅读1分钟

vue3是通过Proxy完成对象的检测,但是问题是如何获取dep, 例如一个对象有10个属性,应该有十个dep对象,但是通过Proxy直接代理一层,如何获取dep

    let proxy = new Proxy(data, {
      get: function (target, key) {
        console.log('监听到获取' + key + target)
        return target[key]
      },
      set: function (target, key, newvalue) {
        console.log('监听到变化' + key + target)
        target[key] = newvalue
        return true
      },
    })
let activeEffect = null
class Dep {
  constructor() {
    this.subscribers = []
  }
  depend() {
    if (activeEffect) {
      this.subscribers.push(activeEffect)
    }
  }
  notify() {
    this.subscribers.forEach((effect) => {
      effect()
    })
  }
}
function watchEffect(effect) {
  activeEffect = effect
  effect()
  activeEffect = null
}

const targetMap = new WeakMap()
function getDep(target, key) {
  let depsMap = targetMap.get(target)
  if (!depsMap) {
    depsMap = new Map()
    targetMap.set(target, depsMap)
  }
  let dep = depsMap.get(key)
  if (!dep) {
    dep = new Dep()
    depsMap.set(key, dep)
  }
  return dep
}

function reactive(raw) {
  return new Proxy(raw, {
    get(target, key, receiver) {
      const dep = getDep(getDep)
      dep.depend()
      return Reflect.get(target, key, receiver)
    },
    set(target, key, value, receiver) {
      const dep = getDep(getDep)
      const result = Reflect.set(target, key, value, receiver)
      dep.notify()
      return result
    },
  })
  // vue2
  // Object.keys(raw).forEach((key) => {
  //   let value = raw[key]
  //   const dep = new Dep()
  //   Object.defineProperty(raw, key, {
  //     get() {
  //       dep.depend()
  //       return value
  //     },
  //     set(newValue) {
  //       value = newValue
  //       dep.notify()
  //     },
  //   })
  // })
  // return raw
}

const state = reactive({
  count: 0,
})

watchEffect(() => {
  console.log(state.count)
  // console.log(state.age)
})