Vue2 响应式原理是什么
先理解原理和示例,再练习完整口述与追问。
回答要点
Object.defineProperty 将已有属性转换为 getter / setter;读取时收集依赖,写入时通知更新。数组依赖变更方法的处理。要能从“改数据”讲到“组件重新渲染”。
原理拆解
Vue2 对初始化数据做观察,把已有可配置属性转换成 getter/setter;每个属性关联依赖容器 Dep。组件首次渲染时,渲染 watcher 成为当前收集目标,模板读取字段会经过 getter,把该 watcher 登记为依赖。setter 收到变化后通知依赖,watcher 进入去重队列,稍后重新运行渲染函数并 patch。对象的嵌套属性会被继续观察,数组则主要通过改写变更方法并观察插入项来通知。
示例与推演
链路可以逐步推演:模板显示 user.name → 首次读取收集该组件 → 执行 user.name = 新值 → setter 通知 → 本轮同步代码继续 → 更新队列执行 → 新 VNode 与旧 VNode 比较 → 更新文本节点。响应式决定哪些计算应重跑,diff 决定重跑后如何更新 DOM,二者职责不同。未被该渲染读取的独立属性变化,不必让这个组件因此重新渲染。
易错点
不要说“数据一变就同步改 DOM”,也不要把 Dep、watcher、虚拟 DOM 当作同一个对象。新增属性和数组下标直接赋值的限制,需要结合 Vue2 实际观察方式解释,而不是泛称 JS 监听不了。
参考回答可直接练习口述
Vue2 会观察 data 中已有的属性,通过 getter 收集当前渲染 watcher 等依赖,通过 setter 通知。多次变更会排队去重,随后重新执行相关渲染并更新 DOM。数组的 push、splice 等方法经过专门处理;新增属性和直接下标赋值存在检测限制。实际排障时我会检查属性是否被观察、修改是否经过可触发路径,以及当前界面是否真的读取了该依赖。