当前位置:首页 > VUE

vue双向绑定的实现

2026-02-22 15:21:47VUE

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}: ${val}`);
      return val;
    },
    set(newVal) {
      if (newVal !== val) {
        console.log(`设置 ${key}: ${newVal}`);
        val = newVal;
        // 触发更新(模拟发布-订阅)
        dep.notify();
      }
    },
  });
}

在 Vue 3.x 中,改用 Proxy 实现更高效的劫持:

function reactive(obj) {
  return new Proxy(obj, {
    get(target, key) {
      console.log(`读取 ${key}`);
      return Reflect.get(target, key);
    },
    set(target, key, value) {
      if (target[key] !== value) {
        console.log(`设置 ${key}: ${value}`);
        Reflect.set(target, key, value);
        // 触发更新
        trigger(target, key);
      }
      return true;
    },
  });
}

依赖收集与发布-订阅

  1. 依赖收集:在 getter 中收集依赖(Watcher),建立数据与视图的关联。

    class Dep {
      constructor() {
        this.subscribers = [];
      }
      depend() {
        if (targetWatcher) {
          this.subscribers.push(targetWatcher);
        }
      }
      notify() {
        this.subscribers.forEach(sub => sub.update());
      }
    }
  2. Watcher:监听数据变化并更新视图。

    class Watcher {
      constructor(vm, key, updateFn) {
        this.vm = vm;
        this.key = key;
        this.updateFn = updateFn;
        targetWatcher = this; // 全局标记当前 Watcher
        this.vm[this.key];    // 触发 getter 收集依赖
        targetWatcher = null;
      }
      update() {
        this.updateFn.call(this.vm, this.vm[this.key]);
      }
    }

指令解析与绑定

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

<input v-model="message">

编译后等效于:

<input 
  :value="message" 
  @input="message = $event.target.value"
>

实现双向绑定的关键步骤

  1. 数据劫持:拦截数据的读写操作。
  2. 依赖收集:在 getter 中记录依赖关系。
  3. 派发更新:在 setter 中通知所有依赖更新。
  4. 指令绑定:将模板指令转换为数据绑定和事件监听。

代码示例(简易实现)

// 简易 Vue 双向绑定实现
class MiniVue {
  constructor(options) {
    this.$data = options.data;
    this.observe(this.$data);
    this.compile(options.el);
  }

  observe(data) {
    Object.keys(data).forEach(key => {
      let value = data[key];
      const dep = new Dep();
      Object.defineProperty(data, key, {
        get() {
          if (targetWatcher) dep.depend();
          return value;
        },
        set(newVal) {
          if (newVal !== value) {
            value = newVal;
            dep.notify();
          }
        },
      });
    });
  }

  compile(el) {
    const element = document.querySelector(el);
    this.walkNodes(element);
  }

  walkNodes(node) {
    if (node.nodeType === 1) { // Element
      Array.from(node.attributes).forEach(attr => {
        if (attr.name.startsWith('v-')) {
          const dir = attr.name.substring(2);
          if (dir === 'model') {
            const key = attr.value;
            node.value = this.$data[key];
            new Watcher(this, key, val => {
              node.value = val;
            });
            node.addEventListener('input', e => {
              this.$data[key] = e.target.value;
            });
          }
        }
      });
    }
    node.childNodes.forEach(child => this.walkNodes(child));
  }
}

总结

  • Vue 2.x 使用 Object.defineProperty 实现数据劫持,Vue 3.x 改用 Proxy
  • 通过发布-订阅模式(Dep/Watcher)实现依赖收集和更新派发。
  • v-model 是语法糖,本质是 :value + @input 的绑定组合。

vue双向绑定的实现

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

相关文章

jquery事件绑定

jquery事件绑定

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

vue如何实现绑定

vue如何实现绑定

数据绑定基础 Vue 通过 v-bind 指令实现动态绑定 HTML 属性或组件 prop。基本语法为 v-bind:属性名="表达式",简写为 :属性名="表达式"。例如绑定 class 或 sty…

vue怎么实现双向

vue怎么实现双向

Vue 双向绑定的实现方式 Vue 中实现双向绑定的核心机制是 v-model 指令,它结合了属性绑定和事件监听,适用于表单元素或自定义组件。 表单元素的双向绑定 在原生表单元素(如 input、…

vue双向绑定如何实现

vue双向绑定如何实现

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

vue简单实现双向绑定

vue简单实现双向绑定

Vue 双向绑定的简单实现 Vue 的双向绑定核心是通过 v-model 指令实现的,它结合了 v-bind 和 v-on 的功能。以下是一个简单的实现方式: 模板部分 <templat…

vue双向数据实现

vue双向数据实现

Vue 双向数据绑定的实现原理 Vue 的双向数据绑定主要通过 v-model 指令实现,其核心是基于数据劫持和发布-订阅模式。 数据劫持(响应式原理) Vue 使用 Object.definePr…