vue 数据绑定的实现
Vue 数据绑定的实现原理
Vue 的数据绑定主要通过响应式系统和虚拟 DOM实现,核心依赖 Object.defineProperty(Vue 2)或 Proxy(Vue 3)。
Vue 2 的实现方式
Vue 2 使用 Object.defineProperty 劫持对象的属性访问和修改。当数据变化时,触发 setter 通知依赖更新。

function defineReactive(obj, key, val) {
Object.defineProperty(obj, key, {
get() {
console.log('get:', key);
return val;
},
set(newVal) {
if (newVal !== val) {
console.log('set:', key);
val = newVal;
// 触发视图更新
}
}
});
}
- 依赖收集:在 getter 中收集依赖(Watcher),在 setter 中通知 Watcher 更新。
- 数组处理:重写数组的变异方法(如
push、pop),在调用时手动触发更新。
Vue 3 的实现方式
Vue 3 改用 Proxy 实现响应式,解决了 Vue 2 中无法检测新增属性、数组索引修改等问题。
function reactive(obj) {
return new Proxy(obj, {
get(target, key) {
console.log('get:', key);
return Reflect.get(target, key);
},
set(target, key, value) {
console.log('set:', key);
return Reflect.set(target, key, value);
}
});
}
- 深层响应式:
Proxy自动递归代理嵌套对象。 - 性能优化:减少初始化时的递归遍历,仅在访问时处理。
模板编译与虚拟 DOM
Vue 将模板编译为渲染函数,生成虚拟 DOM(VNode)。数据变化时,通过对比新旧 VNode 高效更新真实 DOM。

// 示例渲染函数
function render() {
return h('div', { id: 'app' }, this.message);
}
数据绑定类型
-
双向绑定(v-model)
语法糖,组合:value和@input实现表单元素与数据的同步。<input v-model="message"> <!-- 等价于 --> <input :value="message" @input="message = $event.target.value"> -
单向绑定({{ }} 或 v-bind)
数据变化驱动视图更新,但视图变化不会反向影响数据。<div>{{ message }}</div> <div v-bind:title="message"></div>
响应式系统的局限与注意事项
- 对象新增属性:Vue 2 需用
Vue.set(),Vue 3 无此限制。 - 数组变更检测:Vue 2 中直接通过索引修改需用
Vue.set(),或使用变异方法。 - 性能权衡:深层响应式可能带来性能开销,必要时可使用
shallowRef或shallowReactive(Vue 3)。






