美文网首页技术挖掘机-soser
Vue.js双向绑定的实现原理

Vue.js双向绑定的实现原理

作者: fullbook | 来源:发表于2017-02-20 13:34 被阅读788次

    如果觉得不错的话,请点一下赞吧 😊
    本文章会持续更新中。。。

    2016年,vuejs可谓是大放异彩,以迅雷不及掩耳之势赶React超Angular,用惯jquery的我一下子被Vue开篇介绍的双向绑定给惊着了!一下子按捺不住好奇心,打算刨根究底,看看双向绑定到底是怎样实现的?

    目标

    第二个版本:更新AngularJS双向绑定的实现原理
    第三个版本:更新BackboneJS双向绑定的实现原理
    第四个版本:更新ReactJS双向绑定的实现原理

    前言

    发布者-订阅者模式(backbone.js): 一般通过sub, pub的方式实现数据和视图的绑定监听,更新数据方式通常做法是 vm.set('property', value)。
    数据劫持(vue.js): 通过Object.defineProperty()来劫持各个属性的setter,getter,在数据变动时发布消息给订阅者,触发相应的监听回调。(采用数据劫持结合发布者-订阅者模式的方式)

    关于数据绑定

    (1)单向数据绑定
    目前前端框架大都采用MV*的模式,其中M(model)指的是模型,也就是数据;V(view)指的是视图,也就是页面展现的部分。通常,我们需要编写代码,将从服务器获取的数据进行“渲染”并展现到视图上。每当数据有变更时,我们会再次进行渲染,从而更新视图,使得视图与数据保持一致。也就是:

    37341-292112f4548b085a.png

    而另一方面,页面也会通过用户的交互,产生状态、数据的变化,这个时候,我们则编写代码,将视图对数据的更新同步到数据,以致于同步到后台服务器。也就是:

    37341-01e1f8e09f2bdf8e.png
    (2)双向数据绑定 37341-ce55a694c880a802.png

    Backbonejs:Model 到 View 的数据传递,可以在 View 中监听 Model 的 change 事件,每当 Model 更新,View 中重新执行 render。而 View 到 Model 的数据传递,可以监听 View 对应的 DOM 元素的各种事件,在检测到 View 状态变更后,将变更的数据发送到 Model。
    AngularJS:采用“脏值检测”的方式,数据发生变更后,对于所有的数据和视图的绑定关系进行一次检测,识别是否有数据发生了改变,有变化进行处理,可能进一步引发其他数据的改变,所以这个过程可能会循环几次,一直到不再有数据变化发生后,将变更的数据发送到视图,更新页面展现。如果是手动对 ViewModel 的数据进行变更,为确保变更同步到视图,需要手动触发一次“脏值检测”。
    VueJS:采用 ES5 提供的 Object.defineProperty() 方法,监控对数据的操作,从而可以自动触发数据同步。并且,由于是在不同的数据上触发同步,可以精确的将变更发送给绑定的视图,而不是对所有的数据都执行一次检测。

    一、VueJS双向数据绑定实现

    (1)Object.defineProperty简单应用
    <pre>
    var obj = {};
    Object.defineProperty(obj, 'hello', {
    get: function() {
    console.log('get方法获取值');
    },
    set: function(val) {
    console.log('set方法设置的值为:' + val);
    }
    });
    obj.hello; // get方法获取值
    obj.hello = 'Hello World';
    </pre>

    相关文章

      网友评论

      • andot:我是一个java后端,想业余时间学习前端,希望大神多多帮助!!!!
        fullbook:@andot 一起努力
      • RichardBillion:脏值检测与发布订阅相比,在数据绑定上具体是如何实现的呢?对于视图和数据的同步比发布订阅有何进步么?
        angular是个大框架,它是基于什么原因没有使用发布-订阅呢,或者是使用脏值检测又对框架有什么好处呢?

      本文标题:Vue.js双向绑定的实现原理

      本文链接:https://www.haomeiwen.com/subject/fjmlwttx.html