当前位置:首页 > VUE

vue 双向绑定实现

2026-01-16 21:53:43VUE

Vue 双向绑定的实现原理

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

数据劫持

Vue 2.x 使用 Object.defineProperty 劫持对象的属性,在属性被访问或修改时触发 getter 和 setter。Vue 3.x 改用 Proxy 代理整个对象,性能更好且能监听动态新增的属性。

vue 双向绑定实现

// Vue 2.x 数据劫持示例
function defineReactive(obj, key, val) {
  Object.defineProperty(obj, key, {
    get() {
      console.log('get:', val);
      return val;
    },
    set(newVal) {
      if (newVal === val) return;
      console.log('set:', newVal);
      val = newVal;
    }
  });
}

依赖收集

每个响应式属性都有一个 Dep(依赖管理器),用于收集依赖该属性的 Watcher(订阅者)。在 getter 中收集依赖,在 setter 中通知更新。

class Dep {
  constructor() {
    this.subs = [];
  }
  addSub(sub) {
    this.subs.push(sub);
  }
  notify() {
    this.subs.forEach(sub => sub.update());
  }
}

模板编译

Vue 编译器将模板解析为渲染函数,过程中遇到指令(如 v-model)会生成对应的数据绑定代码。v-model 本质是 :value@input 的语法糖。

vue 双向绑定实现

// v-model 的等价形式
<input v-model="message">
// 等同于
<input :value="message" @input="message = $event.target.value">

实现简易双向绑定

以下是一个基于 Object.defineProperty 的极简实现:

function observe(obj) {
  Object.keys(obj).forEach(key => {
    let internalValue = obj[key];
    const dep = new Dep();
    Object.defineProperty(obj, key, {
      get() {
        dep.depend(); // 收集当前活跃的 Watcher
        return internalValue;
      },
      set(newVal) {
        internalValue = newVal;
        dep.notify(); // 通知所有 Watcher 更新
      }
    });
  });
}

class Dep {
  constructor() {
    this.subscribers = [];
  }
  depend() {
    if (activeUpdate) {
      this.subscribers.push(activeUpdate);
    }
  }
  notify() {
    this.subscribers.forEach(sub => sub());
  }
}

let activeUpdate = null;
function autorun(update) {
  function wrappedUpdate() {
    activeUpdate = wrappedUpdate;
    update();
    activeUpdate = null;
  }
  wrappedUpdate();
}

Vue 3 的改进

Vue 3 使用 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);
    }
  });
}

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

相关文章

vue实现双向数据绑定的原理

vue实现双向数据绑定的原理

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

jquery事件绑定

jquery事件绑定

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

vue实现数据绑定

vue实现数据绑定

Vue 数据绑定的实现方式 Vue.js 提供了多种数据绑定方式,主要包括双向绑定 (v-model)、单向绑定 ({{ }} 插值或 v-bind)、以及响应式数据管理。以下是具体实现方法: 双向…

vue实现数组绑定

vue实现数组绑定

Vue 数组绑定的实现方法 Vue 提供了多种方式实现数组的响应式绑定,确保数据变化时视图自动更新。以下是常见的实现方法: 使用 v-for 指令渲染数组 通过 v-for 指令可以遍历数组并渲染…

vue 双向实现原理

vue 双向实现原理

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

实现vue动态绑定

实现vue动态绑定

动态绑定的基本语法 在Vue中,使用v-bind指令或简写:实现动态绑定,将数据属性与HTML元素的属性关联起来。例如动态绑定class或style: <div v-bind:class="{…