当前位置:首页 > VUE

vue双向绑定原理实现

2026-02-21 19:32:45VUE

Vue 双向绑定原理实现

Vue 的双向绑定核心是通过数据劫持结合发布者-订阅者模式实现的,主要依赖 Object.definePropertyProxy(Vue 3)来监听数据变化,并通过事件机制通知视图更新。

数据劫持

通过 Object.definePropertyProxy 拦截对象的属性访问和修改,在属性被访问或修改时触发相应的逻辑。例如,使用 Object.defineProperty 实现数据劫持:

vue双向绑定原理实现

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

const data = {};
defineReactive(data, 'message', 'Hello');
data.message; // 触发 get
data.message = 'World'; // 触发 set

依赖收集与发布订阅

在数据劫持的基础上,需要实现依赖收集和发布订阅机制。当数据变化时,通知所有依赖该数据的订阅者更新视图。

vue双向绑定原理实现

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

let target = null;

function watchEffect(fn) {
  target = fn;
  fn();
  target = null;
}

function defineReactive(obj, key, val) {
  const dep = new Dep();
  Object.defineProperty(obj, key, {
    get() {
      dep.depend();
      return val;
    },
    set(newVal) {
      if (newVal !== val) {
        val = newVal;
        dep.notify();
      }
    }
  });
}

const data = {};
defineReactive(data, 'message', 'Hello');

watchEffect(() => {
  console.log(`数据变化: ${data.message}`);
});

data.message = 'World'; // 触发更新

实现双向绑定

将数据劫持和发布订阅机制结合,实现输入框与数据的双向绑定:

<input id="input" type="text">
<div id="display"></div>
const input = document.getElementById('input');
const display = document.getElementById('display');

const data = {};
defineReactive(data, 'text', '');

watchEffect(() => {
  display.textContent = data.text;
});

input.addEventListener('input', (e) => {
  data.text = e.target.value;
});

Vue 3 的 Proxy 实现

Vue 3 使用 Proxy 替代 Object.defineProperty,可以更好地处理数组和动态新增属性:

function reactive(obj) {
  const handlers = {
    get(target, key, receiver) {
      const result = Reflect.get(target, key, receiver);
      track(target, key);
      return result;
    },
    set(target, key, value, receiver) {
      const oldValue = target[key];
      const result = Reflect.set(target, key, value, receiver);
      if (oldValue !== value) {
        trigger(target, key);
      }
      return result;
    }
  };
  return new Proxy(obj, handlers);
}

const data = reactive({ message: 'Hello' });

function track(target, key) {
  // 依赖收集逻辑
}

function trigger(target, key) {
  // 触发更新逻辑
}

总结

Vue 的双向绑定通过数据劫持监听数据变化,依赖收集和发布订阅机制实现视图与数据的同步。Vue 2 使用 Object.defineProperty,Vue 3 使用 Proxy 提升性能和功能支持。

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

相关文章

php实现双向队列

php实现双向队列

PHP 实现双向队列的方法 双向队列(Deque,Double-ended Queue)是一种允许在队列两端进行插入和删除操作的数据结构。PHP 中可以通过数组或 SplDoublyLinkedLis…

vue 双向实现原理

vue 双向实现原理

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

vue双向绑定实现

vue双向绑定实现

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

vue怎么实现双向

vue怎么实现双向

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

vue实现数组双向绑定

vue实现数组双向绑定

实现数组双向绑定的方法 在Vue中,实现数组的双向绑定通常需要结合v-model指令或自定义事件处理。以下是几种常见的方法: 使用v-model绑定数组 Vue的v-model指令默认支持表单元素…

怎么实现vue双向绑定

怎么实现vue双向绑定

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