vue数据实现双向绑定
Vue 数据双向绑定的实现方法
Vue 通过数据劫持和发布-订阅模式实现双向绑定,核心是 v-model 指令和响应式系统。以下是具体实现方式:
使用 v-model 指令
v-model 是语法糖,默认绑定表单元素的 value 属性并监听 input 事件:
<input v-model="message">
<p>{{ message }}</p>
等价于:

<input :value="message" @input="message = $event.target.value">
自定义组件的双向绑定
在自定义组件中,需显式定义 model 选项并触发更新事件:
Vue.component('custom-input', {
props: ['value'],
template: `
<input
:value="value"
@input="$emit('input', $event.target.value)"
>
`
});
使用时:

<custom-input v-model="message"></custom-input>
响应式原理
Vue 2.x 使用 Object.defineProperty 实现数据劫持:
function defineReactive(obj, key, val) {
Object.defineProperty(obj, key, {
get() { return val; },
set(newVal) {
if (newVal === val) return;
val = newVal;
dep.notify(); // 触发更新
}
});
}
Vue 3.x 改用 Proxy:
const observed = new Proxy(data, {
get(target, key) {
track(target, key); // 依赖收集
return target[key];
},
set(target, key, value) {
target[key] = value;
trigger(target, key); // 触发更新
return true;
}
});
手动实现简单双向绑定
示例代码演示基础原理:
<input id="input">
<span id="text"></span>
<script>
const data = { value: '' };
const input = document.getElementById('input');
const text = document.getElementById('text');
Object.defineProperty(data, 'value', {
set(val) {
input.value = val;
text.innerText = val;
},
get() { return input.value; }
});
input.addEventListener('input', (e) => {
data.value = e.target.value;
});
</script>
注意事项
- 数组和对象需特殊处理,Vue 提供了
Vue.set和数组变异方法 - 动态添加的属性默认非响应式,需使用
Vue.set - Vue 3 的
Proxy可原生监听数组变化和动态属性






