【vue3源码】响应式系统设计

响应式系统的核心思路

● 需要将对象进行get和set双向绑定使用的是proxy
● 既然是双向绑定那么get的时候就需要进行收集依赖函数 set的时候需要触发依赖
● 收集和触发依赖我们使用的是Map,而Map下每个属性对应的依赖函数使用的是Set来储存

实现思路

  1. 首先是响应式的代码,使用的就是es6的proxy方法,一下就是大概的一个伪代码实现方式
let obj = {
  name: "zs",
  age: 15,
};

let handle = {
  get(target, key, receiver) {
    // 在get中进行track收集依赖函数
    return target[key];
  },
  set(target, key, newValue, receiver) {
    target[key] = newValue;
    return true;
  },
};
let proxyObj = new Proxy(obj, handle);
  1. 当get的时候需要收集依赖,收集的容器我们使用的是一个weakMap,weakMap下对应的每个对象都是一个Map,然后每个Map属性下对应的就是Set,Set下存放的就是当前属性对应的依赖函数,当我们执行effect的时候会访问proxyObj.name,此时会触发proxy中的get然后进行track,此时bucket中的结构就是{proxyObj:{name:[effect]}}每个对象下的属性对应一个effect函数。

const bucket = new WeakMap();
let activeEffectFn = null;
function track(target, key) {
  // 每个对象下面对应的属性都有一个副作用函数
  let deps = bucket.get(target);
  if (!deps) {
    bucket.set(target, (deps = new Map()));
  }
  let effectFns = deps.get(key);
  if (!effectFns) {
    deps.set(key, (effectFns = new Set()));
  }
  effectFns.add(activeEffectFn);
}
let handle = {
    get(target, key, receiver) {
      // 在get中进行track收集依赖函数
      track(target, key);
      return target[key];
    },
    set(target, key, newValue, receiver) {
      target[key] = newValue;
      return true;
    },
};
function effect(fn) {
  // 执行effect的fn 会导致执行proxy的get
  activeEffectFn = fn;
  fn();
}
let obj = {
  name: "zs",
  age: 15,
};
let proxyObj = new Proxy(obj, handle);
// 执行副作用函数
effect(() => {
  console.log(proxyObj.name);
});
  1. 当set的时候需要触发依赖,此时就需要根据当前对象以及属性找到对应的依赖函数,并触发
const bucket = new WeakMap();
let activeEffectFn = null;
function track(target, key) {
  // 每个对象下面对应的属性都有一个副作用函数
  let deps = bucket.get(target);
  if (!deps) {
    bucket.set(target, (deps = new Map()));
  }
  let effectFns = deps.get(key);
  if (!effectFns) {
    deps.set(key, (effectFns = new Set()));
  }
  effectFns.add(activeEffectFn);
}
let handle = {
    get(target, key, receiver) {
      // 在get中进行track收集依赖函数
      track(target, key);
      return target[key];
    },
    set(target, key, newValue, receiver) {
      target[key] = newValue;
      trigger(target, key);
      return true;
    },
};
function effect(fn) {
  // 执行effect的fn 会导致执行proxy的get
  activeEffectFn = fn;
  fn();
}
let obj = {
  name: "zs",
  age: 15,
};
let proxyObj = new Proxy(obj, handle);
// 执行副作用函数
effect(() => {
  console.log(proxyObj.name);
});
// 触发set 执行trigger
proxyObj.name = "ls";

最后赋上gitee的链接,里面有大致的响应式设计原理包含computed和watcher从简单到复杂,包含一些注释,以及坑点,如有兴趣课以给个star,感谢

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值