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;
    
  • 相关阅读:
    jquery基本用法
    js里BOM和DOM操作
    js基础语法
    java将json格式的字符串转化为对象数组
    Java生成Excel并导入数据
    mybatis的xml中使用foreach循环拼接(sql中的 in 语法)
    FreeMarker在List中取任意一条数据的某一个值
    freemarker中的常用语法
    Java将日期转化为大写格式(阿拉伯大写数字)
    项目中出现The import javax.servlet cannot be resolved 的解决方法
  • 原文地址:https://www.cnblogs.com/Lewiskycc/p/14325818.html
Copyright © 2011-2022 走看看