当前位置:首页 > VUE

vue 双向绑定 实现原理

2026-01-20 11:14:59VUE

Vue 双向绑定的实现原理

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

数据劫持(Data Observation)

Vue 2.x 使用 Object.defineProperty 对数据的 gettersetter 进行劫持。当访问或修改数据时,会触发对应的钩子函数。

// 简化版数据劫持示例
function defineReactive(obj, key, val) {
  Object.defineProperty(obj, key, {
    get() {
      console.log(`读取 ${key}: ${val}`);
      return val;
    },
    set(newVal) {
      if (newVal === val) return;
      console.log(`设置 ${key}: ${newVal}`);
      val = newVal;
      // 触发更新
    },
  });
}

Vue 3.x 改用 Proxy,可以直接监听对象而非属性,且能拦截更多操作(如数组方法)。

// Vue 3.x 使用 Proxy
const observed = new Proxy(data, {
  get(target, key) {
    track(target, key); // 依赖收集
    return target[key];
  },
  set(target, key, value) {
    target[key] = value;
    trigger(target, key); // 触发更新
  },
});

依赖收集(Dependency Tracking)

通过 Dep 类(依赖管理器)和 Watcher 类(订阅者)实现:

  • 每个响应式属性有一个 Dep 实例,用于存储依赖它的 Watcher
  • getter 中调用 dep.depend() 收集当前 Watcher
  • setter 中调用 dep.notify() 通知所有 Watcher 更新。
class Dep {
  constructor() {
    this.subscribers = [];
  }
  depend() {
    if (targetWatcher) {
      this.subscribers.push(targetWatcher);
    }
  }
  notify() {
    this.subscribers.forEach(sub => sub.update());
  }
}

模板编译(Template Compilation)

Vue 的模板会被编译成渲染函数(render),过程中解析指令(如 v-model):

  • v-model 本质是 v-bind + v-on 的语法糖。
  • 对于输入框,v-model 会动态绑定 value 并监听 input 事件。
<input v-model="message">
<!-- 等价于 -->
<input :value="message" @input="message = $event.target.value">

双向绑定的实现流程

  1. 初始化阶段:通过数据劫持监听所有响应式属性。
  2. 编译阶段:解析模板,为每个绑定创建 Watcher,触发 getter 完成依赖收集。
  3. 更新阶段:数据变化时触发 setter,通知 Watcher 更新视图。

示例代码(简化版)

// 数据劫持 + 依赖收集
let targetWatcher = null;

class Watcher {
  constructor(updateFn) {
    this.updateFn = updateFn;
    targetWatcher = this;
    updateFn(); // 触发 getter
    targetWatcher = null;
  }
  update() {
    this.updateFn();
  }
}

function observe(data) {
  for (let key in data) {
    let val = data[key];
    const dep = new Dep();
    Object.defineProperty(data, key, {
      get() {
        dep.depend();
        return val;
      },
      set(newVal) {
        val = newVal;
        dep.notify();
      },
    });
  }
}

// 使用
const data = { message: "Hello" };
observe(data);

new Watcher(() => {
  console.log(`DOM 更新: ${data.message}`);
});

data.message = "World"; // 触发更新

总结

  • Vue 2.x:基于 Object.defineProperty,需递归遍历对象,对数组方法重写。
  • Vue 3.x:基于 Proxy,支持动态新增属性,性能更优。
  • 核心思想:数据劫持 + 依赖收集 + 事件监听

vue 双向绑定 实现原理

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

相关文章

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

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

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

vue实现绑定输入参数

vue实现绑定输入参数

Vue 实现绑定输入参数 在 Vue 中,可以通过 v-model 指令实现输入框与数据的双向绑定。以下是一个简单的示例: <template> <div> &l…

vue实现事件绑定的是

vue实现事件绑定的是

Vue 事件绑定实现方式 Vue 通过 v-on 指令实现事件绑定,语法为 v-on:事件名="处理方法" 或简写为 @事件名="处理方法"。以下是具体实现方法和示例: 基础事件绑定 <…

实现vue双向绑定

实现vue双向绑定

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

react如何绑定事件

react如何绑定事件

React 事件绑定方法 在 React 中绑定事件有多种方式,以下是常见的几种方法: 使用 onClick 或其他事件属性直接绑定 <button onClick={() => co…

jquery绑定事件

jquery绑定事件

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