当前位置:首页 > VUE

vue双向数据绑定实现

2026-02-20 19:37:38VUE

Vue 双向数据绑定的实现原理

Vue 的双向数据绑定是通过结合数据劫持发布-订阅模式实现的,核心依赖于 Object.defineProperty(Vue 2.x)或 Proxy(Vue 3.x)。以下是具体实现机制:

数据劫持(响应式系统)

通过 Object.definePropertyProxy 拦截对象的属性读写操作,实现数据变化的监听。

Vue 2.x 实现:

function defineReactive(obj, key, val) {
  Object.defineProperty(obj, key, {
    get() {
      console.log(`读取 ${key}: ${val}`);
      return val;
    },
    set(newVal) {
      if (newVal !== val) {
        console.log(`设置 ${key}: ${newVal}`);
        val = newVal;
        // 触发更新(通知依赖)
      }
    }
  });
}

Vue 3.x 实现(Proxy):

function reactive(obj) {
  return new Proxy(obj, {
    get(target, key) {
      console.log(`读取 ${key}`);
      return Reflect.get(target, key);
    },
    set(target, key, newVal) {
      if (newVal !== target[key]) {
        console.log(`设置 ${key}: ${newVal}`);
        Reflect.set(target, key, newVal);
        // 触发更新
      }
      return true;
    }
  });
}

依赖收集与发布-订阅

  1. 依赖收集:在属性的 getter 中,将当前正在执行的组件或计算属性(Watcher)添加到依赖列表。
  2. 通知更新:在属性的 setter 中,通知所有依赖(Watcher)触发更新。

简化实现:

class Dep {
  constructor() {
    this.subscribers = new Set();
  }
  depend() {
    if (activeWatcher) {
      this.subscribers.add(activeWatcher);
    }
  }
  notify() {
    this.subscribers.forEach(watcher => watcher.update());
  }
}

let activeWatcher = null;
class Watcher {
  constructor(updateFn) {
    this.updateFn = updateFn;
    this.update();
  }
  update() {
    activeWatcher = this;
    this.updateFn();
    activeWatcher = null;
  }
}

模板编译与绑定

  1. 解析模板:将模板中的指令(如 v-model)解析为数据绑定和事件监听。
  2. 绑定事件:为表单元素(如 input)添加事件监听,将用户输入同步到数据层。

v-model 的等价展开:

vue双向数据绑定实现

<input v-model="message">
<!-- 等价于 -->
<input :value="message" @input="message = $event.target.value">

双向绑定的完整流程

  1. 数据劫持拦截对 data 的访问和修改。
  2. 模板编译时,为每个绑定创建 Watcher,并在首次渲染时触发 getter 收集依赖。
  3. 用户输入触发事件,修改数据并触发 setter,通知所有依赖更新视图。

对比 Vue 2.x 与 Vue 3.x

特性 Vue 2.x(Object.defineProperty) Vue 3.x(Proxy)
监听方式 递归遍历对象属性逐个劫持 直接代理整个对象
数组监听 需重写数组方法(如 push 原生支持数组变化
性能 初始化时递归性能较差 按需代理,性能更优
新属性响应 需手动调用 Vue.set 自动响应新增属性

实现双向绑定的关键点

  • 数据劫持的局限性Object.defineProperty 无法检测到对象属性的添加或删除(Vue 2.x 需用 Vue.set)。
  • 异步更新队列:Vue 会将多次数据变更合并为一次视图更新,通过 nextTick 实现。
  • 虚拟 DOM 优化:通过 Diff 算法最小化 DOM 操作,提升性能。

标签: 绑定双向
分享给朋友:

相关文章

vue双向实现数据

vue双向实现数据

Vue 双向数据绑定的实现原理 Vue 的双向数据绑定主要通过 v-model 指令实现,其核心是结合了数据劫持(Object.defineProperty 或 Proxy)和发布-订阅模式。以下是具…

怎么用vue.js实现双向绑定

怎么用vue.js实现双向绑定

使用 v-model 指令实现双向绑定 Vue.js 提供了 v-model 指令用于在表单输入元素(如 input、textarea、select)上实现双向数据绑定。v-model 会根据控件类型…

vue双向实现原理

vue双向实现原理

Vue 双向数据绑定的实现原理 Vue 的双向数据绑定主要通过数据劫持结合发布-订阅模式实现,核心是 Object.defineProperty(Vue 2.x)或 Proxy(Vue 3.x)。…

vue双向绑定实现

vue双向绑定实现

Vue 双向绑定实现原理 Vue 的双向绑定主要通过 v-model 指令实现,其核心是结合数据劫持(Object.defineProperty 或 Proxy)和发布-订阅模式。 数据劫持 Vue…

实现vue数组双向绑定

实现vue数组双向绑定

Vue 数组双向绑定的实现方法 Vue 通过数据劫持和发布-订阅模式实现数据的双向绑定,但直接修改数组的某些方法(如索引赋值)无法触发视图更新。以下是实现数组双向绑定的几种方法: 使用 Vue.se…

vue双向绑定实现方式

vue双向绑定实现方式

Vue 双向绑定的实现方式 Vue 的双向绑定主要通过 v-model 指令实现,结合数据劫持和发布-订阅模式完成数据与视图的同步更新。以下是核心实现原理及方式: 数据劫持(响应式原理) Vue 使…