当前位置:首页 > 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()或ES6的Proxy来劫持各个属性的getter和setter…

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

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

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

vue实现双向绑定

vue实现双向绑定

Vue 双向绑定的实现原理 Vue 的双向绑定是通过 v-model 指令实现的,其本质是语法糖,结合了 v-bind(属性绑定)和 v-on(事件监听)。以下是具体实现方式: 使用 v-mode…

vue实现事件绑定的是

vue实现事件绑定的是

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

vue实现双向

vue实现双向

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

uniapp怎么给标签绑定颜色

uniapp怎么给标签绑定颜色

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