当前位置:首页 > VUE

vue 双向绑定实现

2026-03-29 14:20:03VUE

Vue 双向绑定的实现原理

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

基于 Object.defineProperty 的实现(Vue 2.x)

  1. 数据劫持
    通过 Object.defineProperty 劫持对象的属性,在属性被访问或修改时触发 gettersetter

    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;
          }
        }
      });
    }
  2. 依赖收集
    getter 中收集依赖(Watcher),在 setter 中通知依赖更新。

    class Dep {
      constructor() {
        this.subscribers = new Set();
      }
      depend() {
        if (currentWatcher) {
          this.subscribers.add(currentWatcher);
        }
      }
      notify() {
        this.subscribers.forEach(watcher => watcher.update());
      }
    }
    
    let currentWatcher = null;
    function defineReactive(obj, key, val) {
      const dep = new Dep();
      Object.defineProperty(obj, key, {
        get() {
          dep.depend(); // 收集依赖
          return val;
        },
        set(newVal) {
          if (newVal !== val) {
            val = newVal;
            dep.notify(); // 通知更新
          }
        }
      });
    }
  3. Watcher 实现
    Watcher 负责订阅数据变化并执行回调(如更新视图)。

    class Watcher {
      constructor(fn) {
        this.fn = fn;
        this.update();
      }
      update() {
        currentWatcher = this;
        this.fn();
        currentWatcher = null;
      }
    }

基于 Proxy 的实现(Vue 3.x)

Vue 3.x 使用 Proxy 替代 Object.defineProperty,解决了深层对象监听和数组监听的问题。

function reactive(obj) {
  return new Proxy(obj, {
    get(target, key) {
      track(target, key); // 依赖收集
      return target[key];
    },
    set(target, key, value) {
      target[key] = value;
      trigger(target, key); // 触发更新
      return true;
    }
  });
}

function track(target, key) {
  // 收集依赖逻辑
}

function trigger(target, key) {
  // 触发更新逻辑
}

双向绑定的完整流程

  1. 模板编译
    Vue 模板编译时解析指令(如 v-model),生成渲染函数和更新函数。

  2. 数据响应式
    通过数据劫持或 Proxy 监听数据变化,建立依赖关系。

  3. 依赖更新
    数据变化时触发 setterProxy.set,通知 Watcher 更新视图。

  4. 视图更新
    Watcher 调用渲染函数更新 DOM,完成双向绑定。

示例代码

以下是一个简化的双向绑定实现:

vue 双向绑定实现

// 数据劫持
function defineReactive(obj, key, val) {
  const dep = new Dep();
  Object.defineProperty(obj, key, {
    get() {
      dep.depend();
      return val;
    },
    set(newVal) {
      if (newVal !== val) {
        val = newVal;
        dep.notify();
      }
    }
  });
}

// 依赖管理
class Dep {
  constructor() {
    this.subscribers = new Set();
  }
  depend() {
    if (currentWatcher) {
      this.subscribers.add(currentWatcher);
    }
  }
  notify() {
    this.subscribers.forEach(watcher => watcher.update());
  }
}

// Watcher
class Watcher {
  constructor(fn) {
    this.fn = fn;
    this.update();
  }
  update() {
    currentWatcher = this;
    this.fn();
    currentWatcher = null;
  }
}

// 测试
const data = { text: 'Hello' };
defineReactive(data, 'text', data.text);

new Watcher(() => {
  console.log('视图更新:', data.text);
});

data.text = 'World'; // 输出 "视图更新: World"

总结

  • Vue 2.x 使用 Object.defineProperty 实现数据劫持,但无法监听数组和深层对象。
  • Vue 3.x 使用 Proxy 解决上述问题,性能更好。
  • 双向绑定的核心是依赖收集和发布-订阅模式。

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

相关文章

jquery绑定事件

jquery绑定事件

jQuery 绑定事件的方法 jQuery 提供了多种方式来绑定事件,以下是常见的几种方法: on() 方法 on() 是最推荐的事件绑定方法,支持动态元素和多个事件绑定。 $(selector)…

vue双向实现数据

vue双向实现数据

Vue 双向数据绑定的实现 Vue 的双向数据绑定主要通过 v-model 指令实现,它结合了 v-bind 和 v-on 的功能,能够同步表单输入和应用状态。 基本语法 在表单元素上使用 v-mo…

vue实现绑定herf

vue实现绑定herf

在 Vue 中绑定 href 的方法 Vue 中可以通过 v-bind 指令或简写 : 动态绑定 href 属性,支持绑定静态值、动态变量或计算属性。 静态绑定 <a href="https…

vue如何实现绑定

vue如何实现绑定

数据绑定基础 Vue 通过 v-bind 指令实现动态绑定 HTML 属性或组件 prop。基本语法为 v-bind:属性名="表达式",简写为 :属性名="表达式"。例如绑定 class 或 sty…

vue 双向绑定实现

vue 双向绑定实现

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

vue 实现双向绑定

vue 实现双向绑定

Vue 双向绑定的实现原理 Vue 的双向绑定主要通过 v-model 指令实现,底层基于数据劫持和发布-订阅模式。以下是核心实现机制: 数据劫持(响应式系统) Vue 使用 Object.defi…