vue实现双休绑定
Vue 实现双向绑定
Vue 实现双向绑定的核心机制是结合数据劫持(通过 Object.defineProperty 或 Proxy)和发布-订阅模式。以下是具体实现方式:
数据劫持
通过 Object.defineProperty 或 ES6 的 Proxy 监听数据变化。Vue 2.x 使用 Object.defineProperty,Vue 3.x 升级为 Proxy。

// Vue 2.x 数据劫持示例
function defineReactive(obj, key, val) {
Object.defineProperty(obj, key, {
get() {
return val;
},
set(newVal) {
if (newVal !== val) {
val = newVal;
// 触发更新
dep.notify();
}
}
});
}
依赖收集
每个响应式数据关联一个 Dep(依赖收集器),用于存储所有依赖该数据的 Watcher 实例。

class Dep {
constructor() {
this.subs = [];
}
addSub(sub) {
this.subs.push(sub);
}
notify() {
this.subs.forEach(sub => sub.update());
}
}
模板编译
Vue 编译器将模板解析为渲染函数,过程中遇到 v-model 等指令时会创建对应的 Watcher,并触发数据的 getter 完成依赖收集。
// 简化的 Watcher 示例
class Watcher {
constructor(vm, exp, cb) {
this.vm = vm;
this.getter = parsePath(exp);
this.cb = cb;
this.value = this.get();
}
get() {
Dep.target = this;
const value = this.getter.call(this.vm, this.vm);
Dep.target = null;
return value;
}
update() {
const oldValue = this.value;
this.value = this.get();
this.cb.call(this.vm, this.value, oldValue);
}
}
双向绑定实现
v-model 是语法糖,本质是 :value 绑定和 @input 事件监听的组合:
<input v-model="message">
<!-- 等价于 -->
<input :value="message" @input="message = $event.target.value">
完整流程
- 初始化时通过数据劫持监听所有响应式数据。
- 模板编译过程中为每个依赖创建
Watcher,触发getter将Watcher添加到Dep中。 - 数据变化时触发
setter,调用Dep.notify()通知所有Watcher更新视图。
注意事项
- Vue 3.x 使用
Proxy替代Object.defineProperty,解决了数组监听和对象新增属性的限制。 - 自定义组件实现双向绑定需显式定义
model选项和触发update:propName事件。






