参考vue3,手写一个响应式系统

手写一个响应式系统是一个复杂且有趣的任务,它涉及到很多Vue 3内部的核心概念,如Proxy、Reactive Effect、Dependency Tracking等。下面是一个简化的响应式系统的实现,以帮助你理解其基本原理。

// 创建一个存储所有响应式对象的WeakMap,用于依赖收集和触发更新
const targetMap = new WeakMap();

// 创建一个简单的依赖类
class Dep {
  constructor() {
    this.subscribers = new Set();
  }

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

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

// 当前活动的Reactive Effect
let activeEffect = null;

// 创建一个响应式Effect函数
function effect(fn) {
  const run = () => {
    try {
      activeEffect = run;
      fn();
    } finally {
      activeEffect = null;
    }
  };
  run();
  return run;
}

// 创建一个将对象转换为响应式对象的函数
function reactive(obj) {
  // 如果对象已经是响应式的,则直接返回
  if (targetMap.has(obj)) {
    return targetMap.get(obj);
  }

  const originalObj = obj;
  const observed = new Proxy(originalObj, {
    get(target, key, receiver) {
      const dep = getDep(target, key);
      dep.depend();
      return Reflect.get(target, key, receiver);
    },
    set(target, key, value, receiver) {
      const result = Reflect.set(target, key, value, receiver);
      const dep = getDep(target, key);
      dep.notify();
      return result;
    },
    deleteProperty(target, key) {
      const result = Reflect.deleteProperty(target, key);
      const dep = getDep(target, key);
      dep.notify();
      return result;
    },
  });

  // 使用WeakMap存储原始对象和对应的依赖集合
  targetMap.set(originalObj, observed);
  return observed;
}

// 获取或创建一个对象的依赖集合
function getDep(target, key) {
  let depMap = targetMap.get(target);
  if (!depMap) {
    depMap = new Map();
    targetMap.set(target, depMap);
  }
  let dep = depMap.get(key);
  if (!dep) {
    dep = new Dep();
    depMap.set(key, dep);
  }
  return dep;
}

// 使用示例:
const state = reactive({ count: 0 });
effect(() => {
  console.log("Count changed:", state.count);
});
state.count = 1; // 触发effect函数,输出:Count changed: 1

这个简化的响应式系统实现了Vue 3中的核心功能,包括将对象转换为响应式对象、依赖收集和触发更新。当你修改响应式对象的属性时,所有依赖于该属性的effect函数都会被重新执行。这只是一个基本的实现,Vue 3的响应式系统还包含了许多其他功能和优化,如计算属性、watch、ref、toRefs等。

posted @ 2025-01-05 09:22  王铁柱6  阅读(52)  评论(0)    收藏  举报