vue双向绑定实现例子
Vue 双向绑定实现示例
Vue 的双向绑定通过 v-model 指令实现,本质是语法糖,结合了 v-bind(属性绑定)和 v-on(事件监听)。以下是具体实现示例和原理说明。
基础示例
<template>
<div>
<input v-model="message" placeholder="输入内容">
<p>输入的内容是:{{ message }}</p>
</div>
</template>
<script>
export default {
data() {
return {
message: ''
};
}
};
</script>
自定义组件实现双向绑定
在自定义组件中,需通过 model 选项和 $emit 实现:

<template>
<div>
<custom-input v-model="customMessage"></custom-input>
<p>自定义组件输入的值:{{ customMessage }}</p>
</div>
</template>
<script>
export default {
data() {
return {
customMessage: ''
};
},
components: {
'custom-input': {
props: ['value'],
model: {
prop: 'value',
event: 'input'
},
template: `
<input
:value="value"
@input="$emit('input', $event.target.value)">
`
}
}
};
</script>
双向绑定原理
-
数据劫持
Vue 使用Object.defineProperty或Proxy监听数据变化,触发 setter 时更新视图。
-
依赖收集
通过 Dep 类收集依赖(Watcher),数据变化时通知 Watcher 更新。 -
模板编译
将模板中的v-model解析为value属性和input事件监听。
手动实现简化版
// 数据监听
function defineReactive(obj, key, val) {
const dep = new Dep();
Object.defineProperty(obj, key, {
get() {
if (Dep.target) dep.addSub(Dep.target);
return val;
},
set(newVal) {
if (newVal === val) return;
val = newVal;
dep.notify();
}
});
}
// 依赖管理
class Dep {
constructor() {
this.subs = [];
}
addSub(sub) {
this.subs.push(sub);
}
notify() {
this.subs.forEach(sub => sub.update());
}
}
// 观察者
class Watcher {
constructor(vm, key, cb) {
Dep.target = this;
this.cb = cb;
vm._data[key]; // 触发 getter
Dep.target = null;
}
update() {
this.cb();
}
}
注意事项
- 在 Vue 3 中,双向绑定基于
Proxy实现,支持更全面的数据监听。 - 自定义组件中若需复用
v-model,可通过参数传递(如v-model:title)。






