当前位置:首页 > VUE

实现Vue双向数据绑定

2026-02-23 04:56:57VUE

Vue双向数据绑定的实现原理

Vue的双向数据绑定主要通过数据劫持结合发布者-订阅者模式实现,核心是利用Object.defineProperty()Proxy来监听数据变化。

核心实现步骤

数据劫持 通过Object.defineProperty()递归遍历数据对象的属性,将其转换为getter/setter。当数据被访问或修改时触发相应的钩子函数。

function defineReactive(obj, key, val) {
  Object.defineProperty(obj, key, {
    get() {
      return val;
    },
    set(newVal) {
      if (newVal === val) return;
      val = newVal;
      dep.notify(); // 通知所有订阅者
    }
  });
}

依赖收集 每个被劫持的属性都会拥有一个Dep实例,用于收集依赖(Watcher实例)。当属性被访问时,当前Watcher会被添加到Dep中。

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

Watcher Watcher作为观察者,在初始化时会将自身赋值给全局变量,然后触发属性的getter进行依赖收集。当数据变化时,Dep会通知所有Watcher调用update方法更新视图。

class Watcher {
  constructor(vm, exp, cb) {
    this.vm = vm;
    this.exp = exp;
    this.cb = cb;
    this.value = this.get(); // 触发依赖收集
  }
  update() {
    this.run();
  }
  run() {
    const value = this.vm.data[this.exp];
    if (value !== this.value) {
      this.value = value;
      this.cb.call(this.vm, value);
    }
  }
}

完整流程示例

  1. 初始化Vue实例时,对data进行递归遍历,使用Object.defineProperty设置getter/setter
  2. 编译模板时,为每个指令/插值表达式创建Watcher实例
  3. Watcher在初始化时会读取对应数据,触发getter将自身添加到Dep中
  4. 当数据变化时,setter被触发,调用Dep.notify()通知所有Watcher更新视图

现代Vue的改进

Vue 3.0使用Proxy替代Object.defineProperty,优势在于:

  • 直接监听对象而非属性
  • 可监听数组变化
  • 无需递归遍历初始化
function reactive(obj) {
  return new Proxy(obj, {
    get(target, key) {
      track(target, key); // 依赖收集
      return target[key];
    },
    set(target, key, value) {
      target[key] = value;
      trigger(target, key); // 触发更新
      return true;
    }
  });
}

双向绑定的模板实现

对于v-model指令,本质是语法糖:

<input v-model="message">

等价于:

实现Vue双向数据绑定

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

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

相关文章

vue 数据绑定实现

vue 数据绑定实现

Vue 数据绑定的实现方式 Vue 的数据绑定主要通过响应式系统和模板语法实现,以下是核心方法: 双向数据绑定(v-model) 通过 v-model 指令实现表单元素与数据的双向绑定,自动同步数据…

uniapp怎么给标签绑定颜色

uniapp怎么给标签绑定颜色

在 uniapp 中给标签绑定颜色 在 uniapp 中,可以通过动态绑定样式或类名的方式为标签设置颜色。以下是几种常见的方法: 动态绑定内联样式 使用 :style 绑定动态样式对象,直接在标签…

vue 实现循环绑定

vue 实现循环绑定

Vue 实现循环绑定的方法 在 Vue 中,可以通过 v-for 指令实现循环绑定,用于渲染列表或对象数据。以下是几种常见的实现方式: 数组循环绑定 使用 v-for 遍历数组,可以通过索引或直接获…

实现vue动态绑定

实现vue动态绑定

动态绑定的基本语法 在Vue中,使用v-bind指令或简写:实现动态绑定,将数据属性与HTML元素的属性关联起来。例如动态绑定class或style: <div v-bind:class="{…

vue双向数据绑定实现

vue双向数据绑定实现

双向数据绑定的概念 双向数据绑定是指视图(View)与模型(Model)之间的双向同步。当数据发生变化时,视图自动更新;当用户操作视图时,数据也会自动更新。Vue 通过 v-model 指令实现双向数…

怎么实现vue双向绑定

怎么实现vue双向绑定

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