← 返回软件技术总览 软件技术 · 知识点深化 · Vue 响应式原理:从 defineProperty 到 Proxy
软件技术 · 知识点深化 · 前端

Vue 响应式原理:从 defineProperty 到 Proxy

Vue data 一改页面自动更新,背后是响应式系统。Vue2 用 Object.defineProperty 劫持属性,Vue3 改用 Proxy 代理整个对象。这一页讲透依赖收集、派发更新、nextTick。

① 怎么学(4 步走,约 65 分钟)

先建立直觉再抠细节,按这四步走最稳:

1看图建立直觉(10 分钟)
读②③:先在脑子里画出本课核心结构图。
2记完整体系(15 分钟)
读④:把对比表和公式看懂,不要急着背。
3跟例题走一遍(20 分钟)
精读⑤:看三个例题怎么用知识点解题。
4刷题纠错(剩余时间)
做⑦⑩,错题回⑥诊断。
本课小目标学完你要能:① 解释响应式原理;② 对比 Vue2/Vue3;③ 说出 nextTick 原因;④ 解释 computed 缓存。

② 一图看懂:Vue 响应式全景

响应式 数据劫持 get/set 或 Proxy 依赖收集 谁用了这个 data 派发更新 数据变通知 watcher nextTick DOM 更新后回调 应用:双向绑定/计算属性 Vue2/Vue3 易错:Vue2 新增属性不响应 要用 $set
读法:中心是本课主题,四条分支展开核心维度,下方是典型应用与高频易错点。

③ 本质直觉:响应式就是"自动记账"

你改了 data.name,页面自动更新。Vue 怎么知道谁用了 name?

渲染时:组件模板读了 data.name,触发 name 的 getter,Vue 把这个渲染 watcher 记到 name 的依赖列表里(依赖收集)。

修改时:name 被赋值触发 setter,Vue 通知依赖列表里所有 watcher 重新渲染(派发更新)。

Vue2 用 defineProperty:逐个属性劫持,新增/删除属性检测不到,要 $set。Vue3 用 Proxy:代理整个对象,新增属性也能拦截。

data.nameget/set Dep 依赖列表 渲染 Watcher更新 DOM 读时收集依赖,写时通知更新
computed 缓存computed 基于依赖缓存,依赖不变不重算。methods 每次渲染都跑。

④ 完整知识体系

Vue2 vs Vue3 响应式

维度Vue2 definePropertyVue3 Proxy
劫持粒度逐属性整对象
新增属性不响应,要 $set自动响应
数组下标拦截数组方法自动拦截
性能递归遍历初始化惰性代理
Map/Set不支持支持
nextTick数据修改后 DOM 异步更新,nextTick 在更新完成后回调
依赖收集getter 里把当前 watcher 加入 dep

nextTick 为什么需要

Vue 更新 DOM 是异步批量的。你改了 data 立刻读 DOM 还是旧的。nextTick 回调在 DOM 更新后执行。

⑤ 应用场景与例题

例1 Vue2 里给对象加新属性页面不更新
defineProperty 劫持已有属性,新增属性没劫持。用 Vue.set(obj,key,value) 或 this.$set。Vue3 用 Proxy 没这问题。
例2 改了 data 立刻读 DOM 拿到旧值
DOM 异步更新,要 this.$nextTick(() => 读新 DOM)。
例3 computed 和 methods 区别?
computed 缓存,依赖不变不重算;methods 每次渲染都执行。
做题心法读时收集依赖,写时通知 watcher 重新渲染。

⑥ 高频错误诊断(4 条)

错误1:Vue2 新增属性不用 $set页面不响应。
错误2:改完 data 立刻读 DOM读不到新值,用 nextTick。
错误3:computed 里发请求computed 应无副作用,用 watch。
错误4:数组直接改下标Vue2 要 splice 或 $set。

⑦ 考点真题演练(5 题)

考点分布

考法出题形式应对
原理问怎么通知更新依赖收集+派发
Vue2/3问区别Proxy vs defineProperty
nextTick问为什么DOM 异步更新
computed问缓存依赖不变不重算

真题basic1. Vue3 响应式用什么实现?

真题mid2. Vue2 中新增对象属性如何让它响应式?

真题mid3. 修改 data 后立刻读 DOM 是旧值,应该?

真题hard4. computed 相比 methods 的优势?

真题hard5. Vue2 为什么不能检测数组下标修改?

⑧ 必背知识点卡

原理:读收集依赖,写派发更新
Vue2:defineProperty 逐属性 新增要 $set
Vue3:Proxy 整对象 自动响应
nextTick:DOM 异步更新后回调
computed:依赖缓存,无副作用
Watcher:渲染 watcher/computed watcher/user watcher
数组:Vue2 拦截 push/splice 等方法

⑨ 动手输出:解释 Vue 双向绑定流程

场景:输入框 v-model 输入,页面怎么变?
① 输入:input 事件更新 data。
② setter:触发对应属性 setter。
③ 通知:dep 通知渲染 watcher。
④ 更新:watcher 重新渲染 DOM。
⑤ 异步:批量更新,nextTick 后 DOM 是新的。
口述思路响应式 = 数据劫持 + 观察者模式。

⑩ 分层练习(基础 + 中档 + 拔高)

▍基础 6 题

基础1Vue 响应式核心是什么?
数据劫持+依赖收集。
基础2Vue3 用什么代理?
Proxy。
基础3Vue2 新增属性用什么?
$set。
基础4nextTick 解决什么?
DOM 异步更新后读新值。
基础5computed 有缓存吗?
有,依赖不变不重算。
基础6Watcher 有哪几种?
渲染、computed、用户 watch。

▍中档 5 题

中档1为什么 Vue2 不能检测数组下标?
defineProperty 劫持数组元素性能差,改拦截方法。
中档2Vue3 Proxy 优势?
整对象代理,新增属性自动响应,支持 Map/Set。
中档3nextTick 内部原理?
微任务队列,DOM 更新后 flush。
中档4watch 和 computed 区别?
computed 派生值有缓存;watch 执行副作用。
中档5为什么避免滥用 watch?
数据流不清晰,多步 watch 难维护。

▍拔高 5 题

拔高1响应式初始化做了什么?
Vue2 递归遍历 data 给每个属性加 getter/setter。
拔高2Dep 和 Watcher 关系?
每个属性一个 Dep,存依赖它的 Watcher 列表。
拔高3Vue3 为什么惰性代理?
访问到子对象才递归代理,初始化更快。
拔高4nextTick 为什么用微任务?
优先于宏任务,DOM 更新后尽快回调。
拔高5v-model 语法糖?
:value + @input 的语法糖。

⑪ 记忆口诀 + 7 天复习计划

三句口诀① 读收集写通知,响应式自动跑。② Vue2 属性要 $set,Vue3 Proxy 全包。③ nextTick 等 DOM,computed 有缓存。
天任务自检
第 1 天读②③,画依赖收集图流程说清
第 2 天背 Vue2/3 对比 + 基础 6 题区别记住
第 3 天做中档 5 题,写 nextTick 场景理解异步
第 4 天做拔高 5 题,讲 Dep/Watcher关系说清
第 5 天做⑦真题 5 题限时每题 2 分钟
第 6-7 天合书口述 v-model 原理不看资料

← 返回软件技术总览