vue数据实现双向绑定
Vue 数据双向绑定的实现原理
Vue 的数据双向绑定主要通过 v-model 指令实现,结合了数据绑定和事件监听。以下是核心实现方式:
使用 v-model 指令
v-model 是语法糖,自动绑定 value 属性并监听 input 事件。适用于表单元素如 <input>、<textarea> 和 <select>。
<input v-model="message">
<p>{{ message }}</p>
自定义组件的双向绑定
对于自定义组件,需手动实现 v-model。默认情况下,v-model 绑定 value 属性并监听 input 事件。
<custom-input v-model="message"></custom-input>
Vue.component('custom-input', {
props: ['value'],
template: `
<input
:value="value"
@input="$emit('input', $event.target.value)"
>
`
})
修改 v-model 的默认行为
通过组件的 model 选项可以修改 v-model 绑定的属性和事件。
Vue.component('my-checkbox', {
model: {
prop: 'checked',
event: 'change'
},
props: ['checked'],
template: `
<input
type="checkbox"
:checked="checked"
@change="$emit('change', $event.target.checked)"
>
`
})
使用 .sync 修饰符
.sync 修饰符是另一种双向绑定的方式,通过 update:propName 事件实现。
<my-component :title.sync="pageTitle"></my-component>
等价于:
<my-component
:title="pageTitle"
@update:title="pageTitle = $event"
></my-component>
组件内需显式触发更新事件:
this.$emit('update:title', newTitle)
底层原理:数据劫持与发布订阅
Vue 2.x 使用 Object.defineProperty 劫持数据属性的 getter/setter,结合观察者模式实现响应式。
Object.defineProperty(obj, key, {
get() {
return val
},
set(newVal) {
val = newVal
dep.notify() // 通知订阅者更新
}
})
Vue 3.x 改用 Proxy 实现,能监听动态添加的属性。
const proxy = new Proxy(obj, {
get(target, key) {
return Reflect.get(target, key)
},
set(target, key, value) {
Reflect.set(target, key, value)
triggerUpdate() // 触发更新
}
})
注意事项
- 直接修改数组索引或对象属性时需使用
Vue.set或数组的变异方法(如push)。 - 性能敏感场景可考虑手动控制更新(如
v-once或Object.freeze)。 - 避免在模板中使用复杂表达式,优先使用计算属性。







