当前位置:首页 > VUE

vue双向绑定的实现

2026-01-22 00:17:35VUE

Vue 双向绑定的实现原理

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

数据劫持

在 Vue 2.x 中,使用 Object.defineProperty 对对象的属性进行劫持,监听属性的读取和修改操作。

function defineReactive(obj, key, val) {
  Object.defineProperty(obj, key, {
    get() {
      console.log(`读取 ${key}`);
      return val;
    },
    set(newVal) {
      if (newVal === val) return;
      console.log(`设置 ${key} 为 ${newVal}`);
      val = newVal;
    }
  });
}

依赖收集

每个被劫持的属性都有一个对应的 Dep 实例,用于收集依赖(Watcher)。当属性被读取时,当前的 Watcher 会被添加到 Dep 中。

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

观察者模式

Watcher 是一个观察者,当数据变化时,Dep 会通知所有 Watcher 更新视图。

let target = null;
class Watcher {
  constructor(vm, key, cb) {
    target = this;
    this.vm = vm;
    this.key = key;
    this.cb = cb;
    this.value = vm[key]; // 触发 getter,收集依赖
    target = null;
  }
  update() {
    this.value = this.vm[this.key];
    this.cb.call(this.vm, this.value);
  }
}

模板编译

Vue 的模板编译器会将模板中的指令(如 v-model)解析为对应的数据绑定和事件监听。

function compile(node, vm) {
  if (node.nodeType === 1) {
    const attrs = node.attributes;
    for (let i = 0; i < attrs.length; i++) {
      if (attrs[i].nodeName === 'v-model') {
        const name = attrs[i].nodeValue;
        node.addEventListener('input', e => {
          vm[name] = e.target.value;
        });
        node.value = vm[name];
        node.removeAttribute('v-model');
      }
    }
  }
}

Vue 3 的 Proxy 实现

Vue 3 使用 Proxy 替代 Object.defineProperty,可以直接监听对象而非属性,支持数组变化检测。

vue双向绑定的实现

function reactive(obj) {
  return new Proxy(obj, {
    get(target, key) {
      console.log(`读取 ${key}`);
      return target[key];
    },
    set(target, key, value) {
      if (target[key] === value) return true;
      console.log(`设置 ${key} 为 ${value}`);
      target[key] = value;
      return true;
    }
  });
}

双向绑定的实现步骤

  1. 数据劫持:通过 Object.definePropertyProxy 监听数据变化。
  2. 依赖收集:在 getter 中收集依赖,setter 中通知更新。
  3. 模板编译:解析模板中的指令,建立数据与视图的关联。
  4. 观察者模式:Watcher 作为桥梁,连接数据变化和视图更新。

注意事项

  • Vue 2.x 无法检测到对象属性的添加或删除,需使用 Vue.setVue.delete
  • Vue 3 的 Proxy 可以监听整个对象,无需特殊处理动态属性。
  • 双向绑定是 v-model 的语法糖,本质是 :value@input 的组合。

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

相关文章

vue样式绑定实现收藏

vue样式绑定实现收藏

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

vue 绑定实现

vue 绑定实现

Vue 数据绑定实现 Vue 的数据绑定主要通过响应式系统和模板编译实现,以下是核心实现方式: 双向绑定 (v-model) 适用于表单元素,自动同步输入值与 Vue 实例数据: <inpu…

jquery绑定事件

jquery绑定事件

jQuery 绑定事件的方法 jQuery 提供了多种方式来绑定事件,以下是常见的几种方法: on() 方法 on() 是最推荐的事件绑定方法,支持动态元素和多个事件绑定。 $(selector)…

vue实现绑定herf

vue实现绑定herf

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

vue实现数组绑定

vue实现数组绑定

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

vue实现数组元素绑定

vue实现数组元素绑定

Vue 数组元素绑定方法 在 Vue 中实现数组元素绑定需要特别注意响应式更新的问题。以下是几种常见实现方式: 直接索引绑定(不推荐) 直接通过索引修改数组元素不会触发视图更新: this.arr…