zoukankan      html  css  js  c++  java
  • vue3基础知识学习系列(二)响应式原理实现

    使用对象的 set/get 方法 模拟实现 vue3 ref 单数据响应

    const targetMap = new Map();
    let currentEffect;
    class Dep {
      constructor(val) {
        this.effects = new Set();
        this._val = val;
      }
      get value() {
        this.depend();
        return this._val;
      }
      set value(newVal) {
        this._val = newVal;
        this.notice();
      }
      // 收集依赖
      depend() {
        if (currentEffect) {
          this.effects.add(currentEffect);
        }
      }
      // 触发依赖
      notice() {
        this.effects.forEach((effect) => {
          effect();
        });
      }
    }
    function effectWatch(effect) {
      // 依赖收集
      currentEffect = effect;
      effect();
      currentEffect = null;
    }
    
    const dep = new Dep(10);
    let b;
    effectWatch(() => {
      b = dep.value + 10;
      console.log(b); // 初始值打印为 10  dep.value修改后打印为 20
    });
    // 值变更 通知 触发依赖 更新变量
    dep.value = 20;
    

    使用 Proxy/Reflect 实现 vue3 reactive 函数的实现原理

    const targetMap = new Map(); //存储指定key的对象
    let currentEffect;
    class Dep {
      constructor(val) {
        this.effects = new Set();
        this._val = val;
      }
      // 收集依赖
      depend() {
        if (currentEffect) {
          this.effects.add(currentEffect);
        }
      }
      // 触发依赖
      notice() {
        this.effects.forEach((effect) => {
          effect();
        });
      }
    }
    function effectWatch(effect) {
      // 依赖收集
      currentEffect = effect;
      effect();
      currentEffect = null;
    }
    
    function getDep(target, key) {
      // key - dep依赖收集
      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) {
          const dep = getDep(target, key);
          // 依赖收集
          dep.depend();
          return Reflect.get(target, key);
        },
        set(target, key, value) {
          // 触发依赖
          const dep = getDep(target, key);
          const result = Reflect.set(target, key, value);
          dep.notice();
          return result;
        },
      });
    }
    
    const user = reactive({
      age: 19,
    });
    
    let double;
    effectWatch(() => {
      double = user.age;
      console.log(double);
    });
    
    user.age = 20;
    
  • 相关阅读:
    POJ 2187 Beauty Contest(凸包+旋转卡壳)
    POJ 3845 Fractal(计算几何の旋转缩放)
    POJ 1755 Triathlon(线性规划の半平面交)
    POJ 2540 Hotter Colder(半平面交)
    POJ 3525/UVA 1396 Most Distant Point from the Sea(二分+半平面交)
    POJ 3348 Cows(凸包+多边形面积)
    POJ 1228 Grandpa's Estate(凸包唯一性判断)
    POJ 2826 An Easy Problem?!(线段交点+简单计算)
    如何在ARC代码中混编非ARC代码
    给view 添加事件
  • 原文地址:https://www.cnblogs.com/Lewiskycc/p/14325818.html
Copyright © 2011-2022 走看看