vue响应式系统数据劫持

在vue3中,采用Proxy进行代理,从而实现数据劫持。

依赖收集器

class Dep {
  constructor() {
    this.subscribers = new Set();
  }

  depend() {
    if (activeEffect) {
      this.subscribers.add(activeEffect);
    }
  }

  notify() {
    this.subscribers.forEach(effect => {
      effect();
    })
  }
}

let activeEffect = null;
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;
}

vue2

function reactive(data) {
  Object.keys(data).forEach(key => {
    const dep = getDep(data, key);
    let value = data[key];

    Object.defineProperty(data, key, {
      get() {
        //收集依赖
        dep.depend();
        return value;
      },
      set(newValue) {
        if (value !== newValue) {
          value = newValue;
          //触发依赖
          dep.notify();
        }
      }
    })
  })

  return data;
}

vue3

function reactive(data) {
  return new Proxy(data, {
    get(target, key) {
      const dep = getDep(target, key);
      //收集依赖
      dep.depend();
      return target[key];
    },
    set(target, key, newValue) {
      const dep = getDep(target, key);
      target[key] = newValue;
      //触发依赖
      dep.notify();
    }
  })
}

使用Proxy进行数据劫持和 Object.defineProperty的区别

1.使用Object.defineProperty进行数据劫持,是对每一个属性进行了劫持,如果新增元素,需要使用$set将新增的元素进行劫持,而使用Proxy代理则是直接代理了整个对象。所以我们在修改数据是,vue2修改原来的数据就可以进行响应式,在vue3中需要修改的是我们的代理对象proxy。
2.Proxy能够观察的类型比Object.defineProperty更丰富,包括has,delete等操作。
3.Proxy是新标准。但是不兼容IE。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值