原文:http://www.javashuo.com/article/p-yyifgmpb-co.htmlhtml
MVVM 是Model-View-ViewModel 的缩写,它是一种基于前端开发的架构模式,其核心是提供对View 和 ViewModel 的双向数据绑定,这使得ViewModel 的状态改变能够自动传递给 View,即所谓的数据双向绑定。前端
Vue.js 是一个提供了 MVVM 风格的双向数据绑定的 Javascript 库,专一于View 层。它的核心是 MVVM 中的 VM,也就是 ViewModel。 ViewModel负责链接 View 和 Model,保证视图和数据的一致性,这种轻量级的架构让前端开发更加高效、便捷。 jquery
MVC 即 Model-View-Controller 的缩写,就是 模型-视图-控制器 , 也就是说一个标准的Web 应用程序是由这三部分组成的: 后端
View 用来把数据以某种方式呈现给用户。
Model 其实就是数据。
Controller 接收并处理来自用户的请求,并将 Model 返回给用户。
在HTML5 还未火起来的那些年,MVC 做为Web 应用的最佳实践是OK 的,这是由于 Web 应用的View 层相对来讲比较简单,前端所须要的数据在后端基本上均可以处理好,View 层主要是作一下展现,那时候提倡的是 Controller 来处理复杂的业务逻辑,因此View 层相对来讲比较轻量,就是所谓的瘦客户端思想。数组
2010年到2011年,HTML5概念被热炒,受到追捧,2012年,W3C 正式宣布HTML5规范已经正式定稿。2013年我刚进公司就接触了第一个 HTML5 框架 Sench touch, 它是一款用来构建移动应用的HTML5 框架,它将先后端完全分离,前端采用MVC 架构,做为一个独立的项目工程来维护。架构
相对 HTML4 , HTML5 最大的亮点是它为移动设备提供了一些很是有用的功能,使得 HTML5 具有了开发App的能力, HTML5开发App 最大的好处就是跨平台、快速迭代和上线,节省人力成本和提升效率,所以不少企业开始对传统的App进行改造,逐渐用H5代替Native,到2015年的时候,市面上大多数App 或多或少嵌入都了H5 的页面。框架
既然要用H5 来构建 App, 那View 层所作的事,就不只仅是简单的数据展现了,它不只要管理复杂的数据状态,还要处理移动设备上各类操做行为等等。所以,前端也须要工程化,也须要一个相似于MVC 的框架来管理这些复杂的逻辑,使开发更加高效。 但这里的 MVC 又稍微发了点变化:函数
View UI布局,展现数据。
Model 管理数据。
Controller 响应用户操做,并将 Model 更新到 View 上。
这种 MVC 架构模式对于简单的应用来看起是OK 的,也符合软件架构的分层思想。 但实际上,随着H5 的不断发展,人们更但愿使用H5 开发的应用能和Native 媲美,或者接近于原生App 的体验效果,因而前端应用的复杂程度已不一样往日,今非昔比。这时前端开发就暴露出了三个痛点问题:布局
其实,早期jquery 的出现就是为了前端能更简洁的操做DOM 而设计的,但它只解决了第一个问题,另外两个问题始终伴随着前端一直存在。性能
MVVM 由 Model,View,ViewModel 三部分构成,Model 层表明数据模型,也能够在Model中定义数据修改和操做的业务逻辑;View 表明UI 组件,它负责将数据模型转化成UI 展示出来,ViewModel 是一个同步View 和 Model的对象。
在MVVM架构下,View 和 Model 之间并无直接的联系,而是经过ViewModel进行交互,Model 和 ViewModel 之间的交互是双向的, 所以View 数据的变化会同步到Model中,而Model 数据的变化也会当即反应到View 上。
ViewModel 经过双向数据绑定把 View 层和 Model 层链接了起来,而View 和 Model 之间的同步工做彻底是自动的,无需人为干涉,所以开发者只需关注业务逻辑,不须要手动操做DOM, 不须要关注数据状态的同步问题,复杂的数据状态维护彻底由 MVVM 来统一管理。
Vue.js 是采用 Object.defineProperty 的 getter 和 setter,并结合观察者模式来实现数据绑定的。当把一个普通 Javascript 对象传给 Vue 实例来做为它的 data 选项时,Vue 将遍历它的属性,用 Object.defineProperty 将它们转为 getter/setter。用户看不到 getter/setter,可是在内部它们让 Vue 追踪依赖,在属性被访问和修改时通知变化。
Observer 数据监听器,可以对数据对象的全部属性进行监听,若有变更可拿到最新值并通知订阅者,内部采用Object.defineProperty的getter和setter来实现。
Compile 指令解析器,它的做用对每一个元素节点的指令进行扫描和解析,根据指令模板替换数据,以及绑定相应的更新函数。
Watcher 订阅者, 做为链接 Observer 和 Compile 的桥梁,可以订阅并收到每一个属性变更的通知,执行指令绑定的相应回调函数。
Dep 消息订阅器,内部维护了一个数组,用来收集订阅者(Watcher),数据变更触发notify 函数,再调用订阅者的 update 方法。
从图中能够看出,当执行 new Vue() 时,Vue 就进入了初始化阶段,一方面Vue 会遍历 data 选项中的属性,并用 Object.defineProperty 将它们转为 getter/setter,实现数据变化监听功能;另外一方面,Vue 的指令编译器Compile 对元素节点的指令进行扫描和解析,初始化视图,并订阅Watcher 来更新视图, 此时Wather 会将本身添加到消息订阅器中(Dep),初始化完毕。
当数据发生变化时,Observer 中的 setter 方法被触发,setter 会当即调用Dep.notify(),Dep 开始遍历全部的订阅者,并调用订阅者的 update 方法,订阅者收到通知后对视图进行相应的更新。