Vue2 vs Vue3 响应式原理对比

136 阅读2分钟

Vue2 vs Vue3 响应式原理对比

今天来聊聊 Vue2 和 Vue3 的响应式原理,看看它们到底有啥不同!👀
无论是面试还是实战,掌握响应式原理都是 Vue 开发的必备技能哦!


Vue2 的响应式原理

Vue2 的响应式是通过 Object.defineProperty 实现的。

实现步骤:

  1. 数据劫持
    • 使用 Object.defineProperty 对对象的每个属性进行劫持。
    • 当属性被读取时,触发 getter,收集依赖(Watcher)。
    • 当属性被修改时,触发 setter,通知依赖更新。
  1. 依赖收集
    • 每个属性都有一个依赖列表(Dep),用于存储 Watcher。
    • 当数据变化时,Dep 会通知所有 Watcher 更新视图。
  1. 数组处理
    • Vue2 对数组的响应式是通过重写数组的 7 个方法(如 pushpopsplice 等)实现的。

代码示例:

function defineReactive(obj, key, val) {
  const dep = new Dep(); // 依赖列表

  Object.defineProperty(obj, key, {
    get() {
      dep.depend(); // 收集依赖
      return val;
    },
    set(newVal) {
      val = newVal;
      dep.notify(); // 通知依赖更新
    },
  });
}

缺点:

  • 无法监听新增/删除属性:需要使用 Vue.setVue.delete
  • 数组响应式有限:只能通过重写方法实现,无法监听索引或长度变化。

Vue3 的响应式原理

Vue3 的响应式是通过 Proxy 实现的。

实现步骤:

  1. 数据劫持
    • 使用 Proxy 对整个对象进行代理。
    • 当对象被读取或修改时,触发 getset 拦截器。
  1. 依赖收集
    • 通过 track 函数收集依赖(Effect)。
    • 通过 trigger 函数通知依赖更新。
  1. 数组处理
    • Proxy 可以直接监听数组的索引和长度变化,无需特殊处理。

代码示例:

function reactive(obj) {
  return new Proxy(obj, {
    get(target, key, receiver) {
      track(target, key); // 收集依赖
      return Reflect.get(target, key, receiver);
    },
    set(target, key, value, receiver) {
      Reflect.set(target, key, value, receiver);
      trigger(target, key); // 通知依赖更新
      return true;
    },
  });
}

优点:

  • 全面监听:可以监听新增/删除属性,以及数组的索引和长度变化。
  • 性能更好:Proxy 是原生支持的特性,性能优于 Object.defineProperty
  • 代码更简洁:无需特殊处理数组和对象。

📊 Vue2 和 Vue3 响应式对比表

特性Vue2Vue3
实现方式Object.definePropertyProxy
监听对象对象的属性整个对象
监听数组重写数组方法直接监听索引和长度
新增/删除属性不支持(需 Vue.set/Vue.delete支持
性能较低较高
代码复杂度较高较低

总结

  • Vue2:通过 Object.defineProperty 实现响应式,功能有限,性能较低。
  • Vue3:通过 Proxy 实现响应式,功能强大,性能更好。

Vue3 的响应式设计更加现代化,尤其是对数组和对象的全面监听,让开发更加高效!快来试试 Vue3 的新特性吧!