返回

Vue3 Reactive 源码学习 | 用心窥探其奥秘

前端

浸淫 Composition-API 良久,迫切地想要一探源码究竟。这次,我将从 Reactive 着手,带着探索精神,深入其内部运作机制。

Reactive 的职责

Reactive 模块在 Vue3 中扮演着举足轻重的角色。它负责响应式数据的管理,是响应式系统不可或缺的基石。通过它,我们可以轻松实现数据的响应式更新,让视图层自动适应数据变化。

实现原理

Reactive 的核心思想是通过 Proxy 来劫持数据访问。当我们访问响应式数据时,实际上是在和 Proxy 对象交互。Proxy 能够拦截数据访问,并触发依赖收集和更新通知。

具体来说,Reactive 通过以下步骤实现数据响应性:

  1. 创建 Proxy 对象 :使用 Proxy 构造函数为原始数据创建一个代理对象。
  2. 劫持数据访问 :重写对象的取值和赋值操作,在访问和修改数据时触发依赖收集和更新通知。
  3. 依赖收集 :在访问响应式数据时,将当前正在执行的函数收集到依赖列表中。
  4. 更新通知 :当响应式数据发生变化时,通知依赖列表中的所有函数重新执行,从而更新视图。

源码解读

在 Vue3 源码中,Reactive 模块主要包含以下几个文件:

  • packages/reactivity/src/reactive.ts:导出 reactive 函数,用于创建响应式对象。
  • packages/reactivity/src/effect.ts:导出 effect 函数,用于收集依赖并执行副作用。
  • packages/reactivity/src/computed.ts:导出 computed 函数,用于创建计算属性。

响应式对象创建

export function reactive(target: object): object {
  if (isReactive(target)) {
    return target;
  }
  // 创建响应式对象的 Proxy 代理
  return createReactiveObject(target);
}

响应式数据访问

const get = createGetter();
const set = createSetter();

// 在 Proxy 代理中重写取值操作
const targetValue = get(raw[key]);

// 在 Proxy 代理中重写赋值操作
set(raw, key, value);

依赖收集

let activeEffect: ReactiveEffect | undefined;

export function effect(fn: ReactiveEffect) {
  // 将当前函数收集到依赖列表
  activeEffect = fn;
  try {
    // 执行副作用
    fn();
  } finally {
    activeEffect = undefined;
  }
}

更新通知

track(effect);
// 数据更新后通知依赖列表
trigger(effect, deps);

结语

通过对 Reactive 模块源码的解读,我们深入了解了 Vue3 中响应式系统的工作原理。Proxy 的使用、依赖收集和更新通知的机制,共同构成了响应式系统的基础。掌握这些知识,不仅有助于我们理解 Vue3 的内部运作,还能为我们在编写响应式代码时提供更深入的指导。