当前位置:首页 > 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中,使用v-bind指令或简写:实现动态绑定,将数据属性与HTML元素的属性关联起来。例如动态绑定class或style: <div v-bind:class="{…

vue怎么实现绑定

vue怎么实现绑定

数据绑定基础 Vue 通过 v-bind 指令实现单向数据绑定(数据从模型到视图),语法为 v-bind:属性="数据" 或简写为 :属性="数据"。例如绑定 src 属性: <img :…

vue实现数据双向

vue实现数据双向

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

vue双向绑定实现

vue双向绑定实现

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

实现vue数据绑定

实现vue数据绑定

Vue数据绑定的实现方式 Vue.js通过数据劫持和发布-订阅模式实现数据绑定,核心是响应式系统。以下是主要实现方法: 双向数据绑定(v-model) <input v-model="mess…

vue怎样实现数组绑定

vue怎样实现数组绑定

Vue 实现数组绑定的方法 Vue 提供了多种方式来实现数组的绑定,以下是常见的几种方法: 使用 v-for 指令绑定数组 通过 v-for 指令可以遍历数组并渲染列表。语法如下: <ul&…