vue 数据绑定实现
Vue 数据绑定的实现方式
Vue.js 通过数据绑定实现了视图与数据的自动同步,核心机制基于响应式系统。以下是 Vue 数据绑定的主要实现方式:
双向数据绑定(v-model)
v-model 是语法糖,结合了 v-bind 和 v-on,常用于表单元素。
示例代码:
<input v-model="message">
<p>{{ message }}</p>
底层等价于:
<input
:value="message"
@input="message = $event.target.value"
>
单向数据绑定(插值表达式)
使用双大括号 {{ }} 插值表达式实现单向绑定,数据变化自动更新视图。
示例代码:
<span>{{ title }}</span>
属性绑定(v-bind)
通过 v-bind 或简写 : 动态绑定 HTML 属性。
示例代码:
<img :src="imageUrl">
<a :href="link.url">{{ link.text }}</a>
响应式原理实现细节
数据劫持(Object.defineProperty)
Vue 2.x 使用 Object.defineProperty 劫持对象属性的读写操作:
function defineReactive(obj, key) {
let value = obj[key];
Object.defineProperty(obj, key, {
get() {
console.log('读取属性');
return value;
},
set(newVal) {
if (newVal !== value) {
console.log('更新视图');
value = newVal;
}
}
});
}
依赖收集与派发更新
- Dep 类:管理依赖(Watcher 实例)。
- Watcher 类:在属性变化时触发视图更新。
伪代码逻辑:class Dep { constructor() { this.subs = []; } addSub(sub) { this.subs.push(sub); } notify() { this.subs.forEach(sub => sub.update()); } }
class Watcher { update() { / 触发组件重新渲染 / } }
#### Vue 3 的 Proxy 实现
Vue 3 改用 `Proxy` 代理整个对象,解决 Vue 2 中数组和新增属性的监听限制:
```javascript
const reactive = (target) => {
return new Proxy(target, {
get(target, key) {
track(target, key); // 依赖收集
return Reflect.get(target, key);
},
set(target, key, value) {
Reflect.set(target, key, value);
trigger(target, key); // 触发更新
}
});
};
注意事项
- 数组更新检测:Vue 2 中直接通过索引修改数组或修改长度不会触发更新,需使用
Vue.set或数组方法(如push)。 - 对象新增属性:Vue 2 中需使用
Vue.set(obj, 'newKey', value)确保响应式。 - 性能优化:避免绑定过多嵌套数据,复杂计算使用
computed属性。







