36.响应式原理

手写响应式原理-vue3

let activeReactiveFn = null;
class Depend {
  constructor() {
    this.reactiveFns = new Set();
  }
  depend() {
    if (activeReactiveFn) {
      this.reactiveFns.add(activeReactiveFn);
    }
  }
  notify() {
    this.reactiveFns.forEach((fn) => fn());
  }
}

const targetMap = new WeakMap();
const getDepend = (target, key) => {
  let map = targetMap.get(target);
  if (!map) {
    map = new Map();
    targetMap.set(target, map);
  }

  let depend = map.get(key);
  if (!depend) {
    depend = new Depend();
    map.set(key, depend);
  }
  return depend;
};

const watchEffect = (fn) => {
  activeReactiveFn = fn;
  fn(); //执行函数并收集依赖
  activeReactiveFn = null;
};

//传入一个普通对象,返回一个Proxy代理对象
const reactive = (obj) => {
  return new Proxy(obj, {
    //监听获取对象的属性值
    get(target, key, receiver) {
      const depend = getDepend(target, key);
      depend.depend();
      return Reflect.get(target, key, receiver);
    },

    //监听设置对象的属性值
    set(target, key, newVal, receiver) {
      Reflect.set(target, key, newVal, receiver);
      const depend = getDepend(target, key);
      depend.notify();
    },
  });
};
const obj = reactive({
  name: "why",
  age: 18,
});
const info =reactive({
  name: 'koby'
})

//收集每一个依赖obj.name的函数
watchEffect(() => {
  const newName = obj.name;
  console.log(newName);
});

watchEffect(() => {
  console.log(obj.name);
  console.log(obj.age);
});

watchEffect(() => {
  console.log(obj.age);
});
watchEffect(() => {
  console.log(info.name);
});

//当obj.name的值发生改变,所有包含依赖obj.name的代码块的函数都重新执行
obj.name = "lily";

手写响应式原理-vue2

let activeReactiveFn = null;
class Depend {
  constructor() {
    this.reactiveFns = new Set();
  }
  depend() {
    if (activeReactiveFn) {
      this.reactiveFns.add(activeReactiveFn);
    }
  }
  notify() {
    this.reactiveFns.forEach((fn) => fn());
  }
}

const targetMap = new WeakMap();
const getDepend = (target, key) => {
  let map = targetMap.get(target);
  if (!map) {
    map = new Map();
    targetMap.set(target, map);
  }

  let depend = map.get(key);
  if (!depend) {
    depend = new Depend();
    map.set(key, depend);
  }
  return depend;
};

const watchEffect = (fn) => {
  activeReactiveFn = fn;
  fn(); //执行函数并收集依赖
  activeReactiveFn = null;
};

//传入一个普通对象,返回一个Proxy代理对象
const reactive = (obj) => {
  Object.keys(obj).forEach((key) => {
    const value = obj[key];
    Object.defineProperty(obj, key, {
      get() {
        const depend = getDepend(obj, key);
        depend.depend();
        return value;
      },
      set(newVal) {
        value = newVal;
        const depend = getDepend(obj, key);
        depend.notify();
      },
    });
  });
  return obj;
};
const obj = reactive({
  name: "why",
  age: 18,
});
const info = reactive({
  name: "koby",
});

//收集每一个依赖obj.name的函数
watchEffect(() => {
  const newName = obj.name;
  console.log(newName);
});

watchEffect(() => {
  console.log(obj.name);
  console.log(obj.age);
});

watchEffect(() => {
  console.log(obj.age);
});
watchEffect(() => {
  console.log(info.name);
});

//当obj.name的值发生改变,所有包含依赖obj.name的代码块的函数都重新执行
obj.name = "lily";

非常感谢王红元老师的深入JavaScript高级语法让我学习到很多 JavaScript 的知识

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

友情链接更多精彩内容