浅谈vue角,反应数据双向绑定原理分析

  

<强>传统做法

  

前端维护状态,手动操作DOM更新视图。前端框架对服务器数据通过模版进行渲染。当用户产生了一个动作之后,我们通过document.getElementBy……手动进行DOM更新。
  框架帮忙分离数据和视图,后续状态更新需要手动操作DOM,因为框架只管首次渲染,不追踪状态监听变化。

  

<强>双向数据绑定

  

当我们在前端开发中采用MV *的模式时,M -模型,指的是模型,也就是数据,V -视图中,指的是视图,也就是页面展现的部分,通常,我们需要编写代码,将从服务器获取的数据进行“渲染”,展现到视图上。每当数据有变更时,我们会再次进行渲染,从而更新视图,使得视图与数据保持一致。

  

浅谈vue,角,反应数据双向绑定原理分析

  

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

  

浅谈vue,角,反应数据双向绑定原理分析

  

不同的前端MV *框架对于这种模型和视图间的数据同步有不同的处理。在骨干中,模型到视图的数据传递,可以在视图中监听模式的改变事件,每当模型更新,视图中重新执行呈现。而视图到模型的数据传递,可以监听视图对应的DOM元素的各种事件,在检测到视图状态变更后,将变更的数据发送到模型(通过两边的监听事件)。相较于骨干,AngularJS所代表的MVVM框架则更进一步,从框架层面支持这种数据同步机制,而且是双向数据绑定:

  

浅谈vue,角,反应数据双向绑定原理分析

  

在不同的MVVM框架中,实现双向数据绑定的技术有所不同。

  

AngularJS采用“脏值检测”的方式,数据发生变更后,对于所有的数据和视图的绑定关系进行一次检测,识别是否有数据发生了改变,有变化进行处理,可能进一步引发其他数据的改变,所以这个过程可能会循环几次,一直到不再有数据变化发生后,将变更的数据发送到视图,更新页面展现。如果是手动对ViewModel的数据进行变更,为确保变更同步到视图,需要手动触发一次“脏值检测”。

  

VueJS则使用ES5提供的Object.defineProperty()方法,监控对数据的操作,从而可以自动触发数据同步,并且,由于是在不同的数据上触发同步,可以精确的将变更发送给绑定的视图,而不是对所有的数据都执行一次检测。

  

<强> Vue双向数据绑定实现

  

数据与视图的绑定与同步,最终体现在对数据的读写处理过程中,也就是Object.defineProperty()定义的数据,得到函数中.Vue中对于的函数为defineReactive,在精简版实现中,我只保留了一些基本特性:

        函数defineReactive (obj,键,值){   var dep=new dep ();   Object.defineProperty (obj,钥匙,{   可列举的:真的,   可配置:没错,   得到:reactGetter函数(){   如果(Dep.target) {   dep.depend ();   }   返回值;   },   设置:函数reactSetter (newVal) {   如果(value=https://www.yisu.com/zixun/==newVal) {   返回;   其他}{   值=newVal;//如果数据发生改变,则通知所有的观察者(借助dep.notify ())   dep.notify ();   }   }   })   }      

在对数据进行读取时,如果当前有观察家(对数据的观察者,观察者会负责将获取的新数据发送给视图),那将该观察者绑定到当前的数据上(dep.depend(),取决于能否关联当前数据和所有的观察者的依赖关系),是一个检查并记录依赖的过程。而在对数据进行赋值时,如果数据发生改变,则通知所有的观察者(借助dep.notify())。这样,即便是我们手动改变了数据,框架也能够自动将数据同步到视图。

  

<强>数据绑定关系的识别过程

  

Vue和AngularJS中,都是通过在HTML中添加指令的方式,将视图元素与数据的绑定关系进行声明

        id=安馐浴北? lt;形式;   & lt;输入类型=拔谋尽眝模型=皀ame”比;   & lt;/form>      

以上的HTML代码表示该输入元素与名字数据进行绑定。在JS代码中可以这样进行初始化:

        var vm=new Vue ({   埃尔:“#测试”,   数据:{   名称:“sysuzhyupeng”   }   })

浅谈vue角,反应数据双向绑定原理分析