vue2 的双向绑定原理是什么

worktile 其他 15

回复

共3条回复 我来回复
  • 不及物动词的头像
    不及物动词
    这个人很懒,什么都没有留下~
    评论

    Vue2 的双向绑定原理主要是通过使用 Object.defineProperty() 方法来劫持对象的属性,实现数据劫持,从而达到监听数据变化的目的。

    具体步骤如下:

    1. 对于待观测的数据对象,Vue 会遍历对象的属性,并使用 Object.defineProperty() 方法将每个属性转换为“响应式属性”。这样一来,这些属性就可以被 Vue 监听到。

    2. 在使用 Object.defineProperty() 方法转换属性时,会为每个属性创建一个“依赖收集器”,用来存储属性的订阅者列表。在属性的 getter 方法中,会将当前的订阅者添加到依赖收集器中。

    3. 当属性发生变化时,会触发属性的 setter 方法。在 setter 方法中,会通知依赖收集器中的所有订阅者进行更新。

    4. 订阅者在更新时,会通知 Vue 响应式系统,并触发更新队列。Vue 会进行优化,将多次的更新合并成一次,以提高性能。

    5. 更新队列中的更新操作会导致视图进行重新渲染,达到数据和视图的同步更新。

    总的来说,Vue2 的双向绑定原理就是通过数据劫持和观察者模式来实现的。通过劫持对象的属性,当属性发生变化时,会自动通知所有相关的订阅者进行更新,从而实现了数据的自动同步更新到视图上。这种机制使得开发者可以更方便地操作数据,并且不需要手动去更新视图,提高了开发效率。

    2年前 0条评论
  • fiy的头像
    fiy
    Worktile&PingCode市场小伙伴
    评论

    Vue2的双向绑定原理主要基于 数据劫持和观察者模式。

    1. 数据劫持:Vue在初始化时会对数据对象进行遍历,使用Object.defineProperty()方法将每个属性转化为getter和setter。在getter函数中,首先进行依赖收集,将当前的观察者对象(即Watcher对象)添加到依赖中,然后返回属性的值。在setter函数中,首先将新的值与旧的值进行比较,如果发生变化则触发相应的更新操作,通知依赖的观察者对象进行更新。

    2. 观察者模式:Vue使用观察者模式来实现双向绑定。数据对象的每个属性都会对应一个Dep对象,Dep对象用来存储依赖的观察者对象。每个观察者对象都是一个Watcher实例,Watcher对象会在创建时将自身赋值给Dep.target,在getter函数中触发依赖收集时,将Dep.target添加到Dep对象中。当数据发生变化时,setter函数会通知Dep对象,Dep对象会遍历所有依赖的观察者对象并调用其update()方法进行更新操作。

    3. 模板编译:Vue的模板编译过程是将模板字符串转化为渲染函数,渲染函数是一个函数,它接受一个参数h,并返回一个VNode节点。在编译过程中,Vue会解析模板中的指令和插值表达式,将其转化为相应的渲染函数,这样在数据发生变化时,就可以通过触发渲染函数来更新视图。

    4. 依赖收集:在模板编译过程中,对模板中的每个表达式都会创建一个Watcher对象,Watcher对象会在初始化时触发一次表达式的求值,从而触发对应属性的getter函数,并将Watcher对象添加到Dep对象中进行依赖收集。这样在数据发生变化时,就可以通过依赖收集机制找到所有依赖该属性的观察者对象,并进行相应的更新操作。

    5. 活性更新:当数据发生变化时,触发setter函数,通知依赖的观察者对象进行更新。在更新过程中,Vue会根据虚拟DOM的比对算法,只更新实际发生变化的部分,从而提高性能和效率。

    总结起来,Vue2的双向绑定原理是基于数据劫持和观察者模式实现的,通过数据劫持来监听属性的变化,通过观察者模式来建立属性与依赖的关系,并在数据变化时通知依赖进行更新。这样就实现了视图与数据的双向绑定。

    2年前 0条评论
  • worktile的头像
    worktile
    Worktile官方账号
    评论

    Vue2 的双向绑定原理是基于数据劫持和发布-订阅模式实现的。下面将从劫持数据和监听数据变化两个方面来解析双向绑定原理。

    1. 劫持数据

    Vue2 在初始化时会对数据对象进行递归遍历,将每个属性都通过 Object.defineProperty 方法转换为 getter 和 setter,并且在需要监听的属性上添加了一个 Watcher 对象。当数据被访问时,会触发 getter 方法,这时候可以收集订阅者到订阅者列表中。当数据被修改时,会触发 setter 方法,这时候可以通知订阅者更新视图。

    下面是一个简单的例子,展示了数据劫持的实现:

    function defineReactive(data, key, val) {
      Object.defineProperty(data, key, {
        enumerable: true,
        configurable: true,
        get: function() {
          // 如果当前有订阅者,将其添加到订阅者列表中
          if (Dep.target) {
            dep.addSub(Dep.target);
          }
          return val;
        },
        set: function(newVal) {
          if (val === newVal) {
            return;
          }
          val = newVal;
          // 通知订阅者更新视图
          dep.notify();
        }
      });
    }
    
    function observer(data) {
      if (!data || typeof data !== 'object') {
        return;
      }
      Object.keys(data).forEach(function(key) {
        defineReactive(data, key, data[key]);
      });
    }
    
    // 订阅者
    function Watcher(vm, exp, callback) {
      this.vm = vm;
      this.exp = exp;
      this.callback = callback;
      this.value = this.get();
    }
    
    Watcher.prototype = {
      update: function() {
        var value = this.get();
        if (this.value !== value) {
          this.value = value;
          this.callback.call(this.vm, value);
        }
      },
      get: function() {
        // 设置当前订阅者为 Dep.target,进行订阅者收集
        Dep.target = this;
        var value = this.vm.$data[this.exp];
        // 清空当前订阅者
        Dep.target = null;
        return value;
      }
    };
    
    // 订阅者列表
    function Dep() {
      this.subs = [];
    }
    
    Dep.prototype = {
      addSub: function(sub) {
        this.subs.push(sub);
      },
      notify: function() {
        this.subs.forEach(function(sub) {
          sub.update();
        });
      }
    };
    
    // 使用示例
    var data = { name: 'John' };
    observer(data);
    
    new Watcher(data, 'name', function(value) {
      console.log('Name updated: ', value);
    });
    
    data.name = 'Mike'; // 输出 'Name updated: Mike'
    
    1. 监听数据变化

    Vue2 中采用了观察者模式,在数据劫持的过程中,会为每个属性创建一个监听器,用于监听数据的变化。在收集订阅者时,会将订阅者添加到相应属性的监听器中。当数据发生变化时,会通知相应属性的监听器,从而触发订阅者的更新。

    上述代码中的 Dep 类就是一个用于收集订阅者并触发更新的监听器。在劫持数据时,每一个属性都会创建一个 Dep 对象,用于收集订阅者。当数据变化时,会调用 Dep 对象的 notify 方法,通知所有订阅者进行更新。

    另外,需要注意的是,Vue2 的双向绑定只会对使用了指令(v-model) 或者模板中使用的数据进行双向绑定,其他的数据不会进行双向绑定。

    综上所述,Vue2 的双向绑定原理是通过数据劫持和发布-订阅模式实现的。数据劫持实现了对数据的 getter 和 setter 的劫持,以及订阅者的收集和触发;而发布-订阅模式实现了对数据变化的监听和订阅者的更新。通过这两者的配合,实现了数据的双向绑定。

    2年前 0条评论
注册PingCode 在线客服
站长微信
站长微信
电话联系

400-800-1024

工作日9:30-21:00在线

分享本页
返回顶部