实现vue双向绑定
Vue 双向绑定的实现原理
Vue 的双向绑定主要通过 v-model 指令实现,其核心是结合数据劫持(Object.defineProperty 或 Proxy)和发布-订阅模式。以下是具体实现机制:
数据劫持
Vue 2.x 使用 Object.defineProperty 监听对象属性的变化,Vue 3.x 改用 Proxy 实现更高效的响应式系统。
Vue 2.x 示例:
const data = { value: '' };
Object.defineProperty(data, 'value', {
get() {
return this._value;
},
set(newVal) {
this._value = newVal;
console.log('数据更新了'); // 触发视图更新
}
});
Vue 3.x 示例:
const data = { value: '' };
const proxy = new Proxy(data, {
set(target, key, value) {
target[key] = value;
console.log('数据更新了'); // 触发视图更新
return true;
}
});
发布-订阅模式
- 依赖收集:在编译模板时,解析
v-model或其他指令,为每个绑定属性创建一个Watcher(订阅者)。 - 通知更新:当数据变化时,通过
setter或Proxy触发依赖的Watcher,更新视图。
v-model 的实现
v-model 是语法糖,本质是 :value 绑定和 @input 事件监听的组合。
示例代码:
<input v-model="message">
<!-- 等价于 -->
<input :value="message" @input="message = $event.target.value">
自定义组件的双向绑定
在自定义组件中,v-model 默认绑定 value 属性和 input 事件。Vue 3.x 支持自定义 model 选项。
Vue 2.x 实现:
Vue.component('custom-input', {
props: ['value'],
template: `
<input
:value="value"
@input="$emit('input', $event.target.value)"
>
`
});
Vue 3.x 实现:
app.component('custom-input', {
props: ['modelValue'],
emits: ['update:modelValue'],
template: `
<input
:value="modelValue"
@input="$emit('update:modelValue', $event.target.value)"
>
`
});
注意事项
- 性能优化:避免深层对象监听,Vue 3.x 的
Proxy能更好地处理动态属性。 - 数组监听:Vue 2.x 需通过重写数组方法(如
push、splice)实现响应式。






