当前位置:首页 > VUE

实现vue双向绑定

2026-03-28 11:15:17VUE

Vue双向绑定的实现原理

Vue的双向绑定主要通过数据劫持结合发布者-订阅者模式实现。核心是Object.defineProperty或ES6的Proxy来劫持数据属性的gettersetter

使用Object.defineProperty实现

通过Object.defineProperty劫持对象属性的读写操作,在属性被访问或修改时触发相应的回调函数。

function defineReactive(obj, key, val) {
  Object.defineProperty(obj, key, {
    enumerable: true,
    configurable: true,
    get: function() {
      console.log('get value:', val);
      return val;
    },
    set: function(newVal) {
      console.log('set value:', newVal);
      val = newVal;
    }
  });
}

const data = {};
defineReactive(data, 'text', 'hello world');
data.text; // 触发get
data.text = 'new value'; // 触发set

依赖收集与发布订阅

Vue通过Dep类收集依赖(Watcher实例),在数据变化时通知所有订阅者。

实现vue双向绑定

class Dep {
  constructor() {
    this.subs = [];
  }
  addSub(sub) {
    this.subs.push(sub);
  }
  notify() {
    this.subs.forEach(sub => sub.update());
  }
}

class Watcher {
  constructor() {
    Dep.target = this;
  }
  update() {
    console.log('视图更新');
  }
}
Dep.target = null;

完整实现示例

结合数据劫持和依赖收集的简化实现:

function observe(data) {
  if (!data || typeof data !== 'object') return;
  Object.keys(data).forEach(key => {
    defineReactive(data, key, data[key]);
  });
}

function defineReactive(obj, key, val) {
  const dep = new Dep();
  observe(val); // 递归处理嵌套对象
  Object.defineProperty(obj, key, {
    get: function() {
      if (Dep.target) dep.addSub(Dep.target);
      return val;
    },
    set: function(newVal) {
      if (val === newVal) return;
      val = newVal;
      dep.notify();
    }
  });
}

class Vue {
  constructor(options) {
    this._data = options.data;
    observe(this._data);
    new Watcher(); // 模拟渲染过程
  }
}

使用Proxy实现

ES6的Proxy提供了更强大的拦截能力,可以解决Object.defineProperty的一些限制:

实现vue双向绑定

function reactive(obj) {
  return new Proxy(obj, {
    get(target, key) {
      track(target, key);
      return Reflect.get(target, key);
    },
    set(target, key, value) {
      Reflect.set(target, key, value);
      trigger(target, key);
    }
  });
}

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

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

模板编译过程

Vue模板编译将模板转换为渲染函数,过程中会解析指令和插值表达式,创建对应的Watcher:

  1. 解析模板生成AST
  2. 优化AST(标记静态节点)
  3. 生成渲染函数代码
  4. 执行渲染函数触发getter,完成依赖收集

数组的特殊处理

Object.defineProperty无法检测数组变化,Vue通过重写数组方法实现响应式:

const arrayProto = Array.prototype;
const arrayMethods = Object.create(arrayProto);
['push', 'pop', 'shift', 'unshift', 'splice', 'sort', 'reverse'].forEach(method => {
  const original = arrayProto[method];
  arrayMethods[method] = function(...args) {
    const result = original.apply(this, args);
    dep.notify(); // 通知更新
    return result;
  };
});

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

相关文章

vue双向实现数据

vue双向实现数据

Vue 双向数据绑定的实现 Vue 的双向数据绑定主要通过 v-model 指令实现,它结合了 v-bind 和 v-on 的功能,能够同步表单输入和应用状态。 基本语法 在表单元素上使用 v-mo…

vue怎么实现双向

vue怎么实现双向

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

vue 双向绑定 实现原理

vue 双向绑定 实现原理

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

vue双向数据实现

vue双向数据实现

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

vue中实现双向绑定

vue中实现双向绑定

Vue 双向绑定的实现方式 Vue 中实现双向绑定主要通过 v-model 指令,它结合了属性绑定和事件监听,适用于表单元素和自定义组件。 表单元素的双向绑定 在表单元素(如 input、texta…

vue怎么实现input绑定

vue怎么实现input绑定

实现 Vue 中 input 绑定的方法 使用 v-model 指令实现双向绑定 v-model 是 Vue 提供的语法糖,用于实现表单元素与数据的双向绑定。它会根据输入框类型自动选取正确的方式更新数…