当前位置:首页 > 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中,使用v-bind指令或简写:实现动态绑定,将数据属性与HTML元素的属性关联起来。例如动态绑定class或style: <div v-bind:class="{…

vue实现双休绑定

vue实现双休绑定

Vue 实现双向绑定 Vue.js 通过 v-model 指令实现双向绑定,主要用于表单输入元素(如 <input>、<textarea>、<select>)与组件…

实现vue数据绑定

实现vue数据绑定

Vue数据绑定的实现方式 Vue.js通过数据劫持和发布-订阅模式实现数据绑定,核心是响应式系统。以下是主要实现方法: 双向数据绑定(v-model) <input v-model="mes…

实现vue数组双向绑定

实现vue数组双向绑定

Vue 数组双向绑定的实现方法 Vue 通过数据劫持和发布-订阅模式实现数据的双向绑定,但直接修改数组的某些方法(如索引赋值)无法触发视图更新。以下是实现数组双向绑定的几种方法: 使用 Vue.s…

vue怎样实现数组绑定

vue怎样实现数组绑定

Vue 实现数组绑定的方法 Vue 提供了多种方式来实现数组的绑定,以下是常见的几种方法: 使用 v-for 指令绑定数组 通过 v-for 指令可以遍历数组并渲染列表。语法如下: <u…

vue实现数组元素绑定

vue实现数组元素绑定

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