怎么实现vue双向绑定
Vue 双向绑定的实现原理
Vue 的双向绑定主要通过 v-model 指令实现,其核心是结合数据劫持(Object.defineProperty 或 Proxy)和发布-订阅模式。
使用 v-model 实现表单双向绑定
v-model 是语法糖,默认绑定 value 属性并监听 input 事件。以下是一个基础示例:

<template>
<input v-model="message" placeholder="输入内容">
<p>当前输入:{{ message }}</p>
</template>
<script>
export default {
data() {
return {
message: ''
};
}
};
</script>
自定义组件的双向绑定
若需在自定义组件中实现双向绑定,需手动定义 model 选项并触发更新事件:
<template>
<CustomInput v-model="text" />
</template>
<script>
export default {
data() {
return { text: '' };
}
};
</script>
自定义组件 CustomInput.vue:

<template>
<input
:value="value"
@input="$emit('input', $event.target.value)"
>
</template>
<script>
export default {
props: ['value']
};
</script>
底层原理:数据劫持与监听
Vue 2.x 使用 Object.defineProperty 劫持数据,Vue 3.x 改用 Proxy。以下是简化版的响应式实现:
// Vue 2.x 风格的数据劫持
function defineReactive(obj, key) {
let value = obj[key];
const dep = new Dep(); // 依赖收集器
Object.defineProperty(obj, key, {
get() {
dep.depend(); // 收集依赖
return value;
},
set(newVal) {
if (newVal !== value) {
value = newVal;
dep.notify(); // 通知更新
}
}
});
}
手动实现简易双向绑定
以下是一个非框架的原生 JavaScript 实现示例:
<input id="input" />
<p id="display"></p>
<script>
const input = document.getElementById('input');
const display = document.getElementById('display');
let data = { value: '' };
Object.defineProperty(data, 'value', {
get() { return this._value; },
set(newVal) {
this._value = newVal;
display.textContent = newVal; // 更新视图
}
});
input.addEventListener('input', (e) => {
data.value = e.target.value; // 数据变更触发 setter
});
</script>
注意事项
- 修饰符:
v-model支持.lazy(转为change事件)、.number(转为数字)、.trim(去除首尾空格)。 - 多选框/单选组:需绑定数组或布尔值,例如:
<input type="checkbox" v-model="checked" /> - 组件深度绑定:Vue 3 中可使用
v-model:propName指定绑定属性。





