Vue双向绑定由数据劫持和依赖收集与发布-订阅协同两大机制实现:前者通过Object.defineProperty劫持属性getter/setter并重写数组方法,后者通过Dep与Watcher建立数据与视图的响应映射。

Vue的双向绑定依赖于数据与视图之间的动态联动机制,其底层并非单一技术实现,而是由两个紧密协作的核心机制共同支撑。以下是实现该功能的关键路径:
一、数据劫持
该机制负责捕获数据变化,使普通 JavaScript 对象具备响应能力。Vue 2 使用 Object.defineProperty 对 data 中每个属性的 getter 和 setter 进行重定义:getter 在数据读取时触发依赖收集,setter 在数据修改时触发变更通知。对数组则通过重写原型方法(如 push、pop、splice)实现变更拦截;对嵌套对象则递归执行劫持。
1、遍历 data 对象所有自有属性,逐个调用 defineReactive 函数处理。
2、在 defineReactive 内部创建 Dep 实例,用于管理该属性的所有订阅者。
立即学习“前端免费学习笔记(深入)”;
3、当访问属性时,getter 判断当前存在活跃 Watcher,将其添加至该属性对应的 Dep 订阅列表中。
4、当修改属性值时,setter 执行 dep.notify(),遍历并唤醒全部已注册的 Watcher。
二、依赖收集与发布-订阅协同
该机制建立数据变动与视图更新之间的映射关系,确保“一处修改、多处响应”。每个响应式属性拥有独立的 Dep 实例,而每个需要响应数据变化的视图单元(如组件渲染函数、计算属性、v-model 绑定)都对应一个 Watcher 实例。Watcher 在初始化时主动读取相关数据,触发 getter 完成注册;数据变更后,Dep 通知所有关联 Watcher 执行 update 方法。
1、模板编译或 render 函数执行过程中,访问 data 属性触发 getter。
2、此时 Dep.target 指向当前正在创建的 Watcher,该 Watcher 被加入对应属性的 Dep.subs 数组。
3、数据变更触发 setter,进而调用 dep.notify()。
4、Dep 遍历 subs 数组,依次调用每个 Watcher 的 update 方法,驱动视图更新逻辑(如重新执行 render、更新 input 元素 value 值)。










