当前位置:首页 > 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 绑定实现

vue 绑定实现

Vue 绑定实现 Vue 提供了多种数据绑定的方式,包括文本插值、属性绑定、事件绑定、双向绑定等。以下是常见的绑定实现方法: 文本插值 使用双大括号 {{ }} 进行文本插值,将数据动态渲染到 DO…

实现vue双向绑定

实现vue双向绑定

Vue双向绑定的实现原理 Vue的双向绑定主要通过数据劫持结合发布-订阅模式实现。核心是利用Object.defineProperty()或ES6的Proxy来劫持各个属性的getter和setter…

vue双向实现

vue双向实现

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

vue样式绑定实现收藏

vue样式绑定实现收藏

Vue 样式绑定实现收藏功能 在 Vue 中,可以通过动态绑定样式来实现收藏功能,常见的方法是使用 v-bind:class 或 v-bind:style 来切换样式状态。 使用 v-bind:cl…

vue实现双向

vue实现双向

Vue 实现双向绑定的方法 Vue 主要通过 v-model 指令实现双向绑定,适用于表单元素或自定义组件。以下是几种常见实现方式: 表单元素的双向绑定 在表单元素(如 input、textare…

uniapp怎么给标签绑定颜色

uniapp怎么给标签绑定颜色

在 uniapp 中给标签绑定颜色 在 uniapp 中,可以通过动态绑定样式或类名的方式为标签设置颜色。以下是几种常见的方法: 动态绑定内联样式 使用 :style 绑定动态样式对象,直接在…