返回

Vue3 源码揭秘:reactive 响应式背后的魔法

前端

Vue3 源码解析:reactive 响应式工作原理

响应式是 Vue3 的核心特性,它允许我们在数据发生变化时自动更新视图。reactive 函数扮演着至关重要的角色,它将普通对象转换成响应式对象,从而让 Vue3 能够跟踪数据的变化并触发视图更新。

reactive 函数的工作原理

reactive 函数接受一个对象作为参数,并返回一个响应式代理对象。这个代理对象的行为与原始对象类似,但它会在数据变化时自动触发视图更新。

当我们访问响应式代理对象的属性时,Vue3 会收集该属性的依赖关系。这些依赖关系通常是组件中的模板,它们依赖于响应式对象的状态。当响应式对象的属性发生变化时,Vue3 会触发这些依赖关系,导致视图重新渲染。

依赖收集与视图更新

依赖收集的过程发生在每次访问响应式对象的属性时。Vue3 使用一个名为 "追踪器" 的特殊对象来收集依赖关系。当我们访问一个响应式对象的属性时,Vue3 会将当前的追踪器添加到该属性的依赖列表中。

当响应式对象的属性发生变化时,Vue3 会遍历该属性的依赖列表,并触发所有依赖的视图更新。这个过程被称为 "调度器"。

深入源码调试

为了更深入地理解 reactive 函数的工作原理,我们可以调试 Vue3 的源码。在 Vue3 的 packages/reactivity/src/reactive.ts 文件中,我们可以找到 reactive 函数的实现:

export function reactive<T extends object>(target: T): T {
  return createReactiveObject(target, [], []);
}

createReactiveObject 函数负责创建响应式代理对象。它接受三个参数:原始对象、依赖列表和触发器列表。

function createReactiveObject<T extends object>(
  target: T,
  deps: Set<Dep>,
  effects: Set<EffectFn>
) {
  const observed = new Proxy(target, {
    get(target, key, receiver) {
      track(deps, key);
      return Reflect.get(target, key, receiver);
    },
    set(target, key, value, receiver) {
      const oldValue = Reflect.get(target, key, receiver);
      const result = Reflect.set(target, key, value, receiver);
      trigger(effects);
      return result;
    },
  });
  return observed;
}

在 get 拦截器中,当我们访问响应式对象的属性时,track 函数会将当前的追踪器添加到依赖列表中。在 set 拦截器中,当我们修改响应式对象的属性时,trigger 函数会遍历触发器列表并触发所有依赖的视图更新。

总结

通过对 Vue3 reactive 函数的工作原理进行深入解析,我们了解了 Vue3 如何实现响应式。响应式依赖收集和视图更新的机制是 Vue3 强大的数据绑定系统的基石。掌握这些概念对于理解 Vue3 的底层原理和编写高效的 Vue3 应用程序至关重要。