返回

Vue3 源码解析:揭秘 reactive 创建响应式对象的奥秘

前端

引言

在 Vue3 中,reactive 函数是用于创建响应式对象的。响应式对象是指当其属性发生变化时,能够自动触发视图更新的对象。这使得 Vue3 能够轻松实现数据的双向绑定,并极大地简化了前端开发的工作。

reactive 函数的源码实现

export function reactive(target) {
  // 如果 target 不是对象,则直接返回
  if (!isObject(target)) {
    return target;
  }

  // 如果 target 已经是响应式对象,则直接返回
  if (isReactive(target)) {
    return target;
  }

  // 创建响应式对象
  const proxy = createReactiveObject(target);

  // 返回响应式对象
  return proxy;
}

从上面的代码可以看出,reactive 函数是通过调用 createReactiveObject 函数来创建响应式对象的。createReactiveObject 函数的源码实现如下:

function createReactiveObject(target) {
  // 创建一个代理对象
  const proxy = new Proxy(target, {
    // 拦截对象的属性获取操作
    get(target, key, receiver) {
      // 收集依赖
      track(target, key);

      // 获取属性值
      const value = Reflect.get(target, key, receiver);

      // 如果属性值是对象,则将其转换为响应式对象
      if (isObject(value)) {
        return reactive(value);
      }

      // 返回属性值
      return value;
    },

    // 拦截对象的属性设置操作
    set(target, key, value, receiver) {
      // 设置属性值
      const oldValue = Reflect.get(target, key, receiver);
      Reflect.set(target, key, value, receiver);

      // 触发更新
      trigger(target, key, oldValue, value);

      // 返回 true
      return true;
    }
  });

  // 返回代理对象
  return proxy;
}

从上面的代码可以看出,createReactiveObject 函数是通过创建一个 Proxy 对象来实现响应式对象的。Proxy 对象是对目标对象的代理,当我们对 Proxy 对象进行操作时,实际上是对目标对象进行操作。

在 Proxy 对象中,我们定义了 get 和 set 两个拦截器。get 拦截器负责拦截对象的属性获取操作,set 拦截器负责拦截对象的属性设置操作。

在 get 拦截器中,我们首先收集依赖,然后获取属性值。如果属性值是对象,则将其转换为响应式对象。

在 set 拦截器中,我们首先获取旧值,然后设置属性值。接着,我们触发更新,最后返回 true。

总结

通过对 Vue3 中 reactive 函数的源码分析,我们了解了它是如何通过 Proxy 和依赖收集机制创建响应式对象的,以及它是如何实现响应式更新的。

Vue3 的响应式系统是一个非常强大的工具,它极大地简化了前端开发的工作。通过对它的源码进行分析,我们可以对它的工作原理有更深入的理解,并能够更好地利用它来构建复杂的应用程序。