白狗子的博客

「天上浮云如白衣,斯须改变如苍狗。」——杜甫

Vue-面试-响应式原理

2026年10月16日·Admin·1 次浏览

面试题:Vue2 / Vue3 响应式原理有什么区别?

常见问法

  • 「Vue 如何实现双向绑定/响应式?」
  • 「为什么 Vue2 无法检测对象新增属性、数组下标修改?」
  • 「Vue3 为什么改用 Proxy?」

Vue2:基于 Object.defineProperty

对已有属性做 getter / setter 劫持:

  • get:收集依赖(Dep ↔ Watcher,典型的发布-订阅)。
  • set:派发更新,通知相关 Watcher 重新求值 / 渲染。

局限(高频考点)

  1. 无法监听新增/删除属性 → 需 Vue.set / this.$set。
  2. 数组不能直接监听索引与 length,故对「修改元素、变长」等方法做了变异方法重写(push 等)或 $set。
  3. 嵌套对象需在初始化时递归遍历定义属性,大对象有一定初始化成本。

Vue3:基于 Proxy

代理整个对象,拦截 get / set / deleteProperty / has / ownKeys 等:

  • 新增、删除属性天然可追踪。
  • 数组索引与长度变化可被拦截。
  • 依赖收集更懒:访问到哪层才代理哪层(配合 track / trigger)。

底层使用 WeakMap → Map → Set 结构存储 target → key → effects,与 effect(effect 函数、watchEffect 等)联动。

依赖收集与触发(抽象模型)

  1. track(收集):在 get 时,把当前正在运行的 effect 记到该 target + key 的依赖集合里。
  2. trigger(触发):在 set 时,取出依赖集合里的 effect 执行(可能经过调度器批量、异步刷新)。

computed 本质是带缓存的 effect:只有依赖变了才重算。

一句话对比

Vue2 Vue3
API defineProperty Proxy
新增属性 需 API 辅助 直接响应
数组下标 受限 原生支持
兼容性 IE9+(有限) 无 IE,需现代浏览器

© 2025 My Blog. Built with Nuxt.js v4