Vue 3 响应式原理剖析:从 Ref 和 Reactive 到 Proxy 的魔法揭秘 - 指南

如果你使用过 Vue.js,那么你一定对它的响应式系统赞叹不已——当数据变化时,视图会自动更新。这仿佛是魔法一般。但在 Vue 3 中,这个“魔法”的底层实现完成了一次革命性的升级,从 Vue 2 的 Object.defineProperty 全面转向了 ES6 的 Proxy

今天,我们就来揭开这层神秘的面纱,深入探讨 refreactive 这两个核心 API 以及背后的 Proxy 是如何协同工作,构建出 Vue 3 强大而优雅的响应式系统的。

回顾过去:Vue 2 的 Object.defineProperty 与其局限

在深入 Vue 3 之前,我们先快速回顾一下 Vue 2 的实现方式。Vue 2 使用 Object.defineProperty 来递归地遍历数据对象,将每个属性转化为 getter 和 setter。

javascript

// 简化的 Vue 2 响应式原理
function defineReactive(obj, key, val) {
  Object.defineProperty(obj, key, {
    get() {
      console.log(`读取了 ${key}: ${val}`);
      // 这里进行依赖收集(Dep)
      return val;
    },
    set(newVal) {
      if (newVal !== val) {
        console.log(`设置了 ${key}: ${newVal}`);
        val = newVal;
        // 这里通知更新(Watcher)
      }
    }
  });
}

这种方式虽然实用,但存在几个先天缺陷:

  1. 无法检测属性的添加或删除:由于是在初始化时遍历属性,因此后来新增的属性不是响应式的(需要用到 Vue.set)。

  2. 数组响应式需要 hack:直接通过索引设置数组项(arr[index] = newValue)或修改数组长度(arr.length = 0)无法被检测到。

  3. 性能开销:递归遍历整个对象、一次性转化所有属性的方式,在初始化时会有一定的性能成本。

posted @ 2026-01-26 20:43  yangykaifa  阅读(1)  评论(0)    收藏  举报