当前位置:首页 > VUE

vue双向绑定实现函数

2026-01-23 14:18:15VUE

Vue 双向绑定实现原理

Vue 的双向绑定核心是通过数据劫持结合发布者-订阅者模式实现的,主要依赖 Object.definePropertyProxy

vue双向绑定实现函数

使用 Object.defineProperty

function defineReactive(obj, key, val) {
  const dep = new Dep(); // 依赖收集器

  Object.defineProperty(obj, key, {
    enumerable: true,
    configurable: true,
    get() {
      if (Dep.target) {
        dep.addSub(Dep.target); // 收集依赖
      }
      return val;
    },
    set(newVal) {
      if (newVal === val) return;
      val = newVal;
      dep.notify(); // 通知更新
    }
  });
}

// 依赖收集器
class Dep {
  constructor() {
    this.subs = [];
  }
  addSub(sub) {
    this.subs.push(sub);
  }
  notify() {
    this.subs.forEach(sub => sub.update());
  }
}

使用 Proxy(Vue 3 实现)

function reactive(obj) {
  const handler = {
    get(target, key, receiver) {
      track(target, key); // 依赖收集
      return Reflect.get(target, key, receiver);
    },
    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, handler);
}

完整实现示例

class Vue {
  constructor(options) {
    this._data = options.data;
    this.observer(this._data);
    this.compile(options.el);
  }

  observer(data) {
    Object.keys(data).forEach(key => {
      defineReactive(data, key, data[key]);
    });
  }

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

  compileNode(node) {
    if (node.nodeType === 1) {
      Array.from(node.attributes).forEach(attr => {
        if (attr.name.startsWith('v-')) {
          const dir = attr.name.substring(2);
          if (dir === 'model') {
            const exp = attr.value;
            node.value = this._data[exp];
            node.addEventListener('input', e => {
              this._data[exp] = e.target.value;
            });
          }
        }
      });
    }
  }
}

实现要点

数据劫持通过 Object.definePropertyProxy 拦截属性的读取和设置操作

vue双向绑定实现函数

依赖收集在 getter 中完成,将当前 Watcher 添加到 Dep 中

派发更新在 setter 中触发,通知所有依赖进行更新

模板编译时解析指令,建立数据与视图的绑定关系

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

相关文章

vue实现双向绑定

vue实现双向绑定

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

php实现双向队列

php实现双向队列

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

vue如何实现绑定

vue如何实现绑定

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

Vue数据绑定实现

Vue数据绑定实现

Vue 数据绑定的核心机制 Vue 的数据绑定基于响应式系统,通过 Object.defineProperty 或 Proxy 实现。当数据变化时,视图自动更新。 双向绑定的实现方式 v-model…

vue实现数组双向绑定

vue实现数组双向绑定

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

vue简单实现双向绑定

vue简单实现双向绑定

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