当前位置:首页 > 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 进行劫持。当访问或修改数据时,会触发对应的钩子函数。

vue 双向绑定 实现原理

// 简化版数据劫持示例
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 双向绑定 实现原理

// 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实现双向数据绑定的原理

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

jquery事件绑定

jquery事件绑定

jQuery 事件绑定的基本方法 使用 on() 方法绑定事件是最推荐的方式,兼容性强且支持动态元素。语法如下: $(selector).on(eventName, handlerFunction)…

vue双向实现数据

vue双向实现数据

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

vue实现绑定herf

vue实现绑定herf

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

vue 实现循环绑定

vue 实现循环绑定

Vue 实现循环绑定的方法 在 Vue 中,可以通过 v-for 指令实现循环绑定,用于渲染列表或对象数据。以下是几种常见的实现方式: 数组循环绑定 使用 v-for 遍历数组,可以通过索引或直接获…

vue实现数据双向

vue实现数据双向

在Vue中实现数据双向绑定主要依靠v-model指令,它结合了属性绑定和事件监听,适用于表单元素或自定义组件。以下是具体实现方式: 基础表单元素的双向绑定 对于原生表单元素(如input、texta…