一.Vue框架介绍
Vue是一套用于构建用户界面的渐进式框架,设计之初为可以自底向上逐层进行应用。Vue的核心库只关注视图层,不仅易于上手,还便于与第三方库或既有项目整合。另一方面,当与现代化的工具链以及各种支持类库结合使用时,Vue也完全能够为复杂的单页应用提供驱动。
Vue专注于 MVVM 模型的
ViewModel
层。它通过双向数据绑定把
View
层和
Model
层连接了起来。实际的 DOM 封装和输出格式都被抽象为了
Directives
和
Filters。
MVVM框架
MVVM模式的引入就是使用ViewModel来降低View和Model的耦合,说是降低View和Model的耦合。也可以说是是降低界面和逻辑的耦合,理想情况下界面和逻辑是完全分离的,单方面更改界面时不需要对逻辑代码改动,同样的逻辑代码更改时也不需要更改界面。同一个ViewModel可以使用完全不用的View进行展示,同一个View也可以使用不同的ViewModel以提供不同的操作。
MVVM的三个优点:
低耦合、可复用、可测试、易维护。
二.Vue生命周期
下图可以很好地展示Vue的生命周期。
三.Vue原理
实现数据绑定的方法:
-
- 发布者-订阅者模式(backbone.js)
- 脏值检查(angular.js)
- 数据劫持(vue.js)
#发布者-订阅者模式(backbone.js)
一般通过sub, pub的方式实现数据和视图的绑定监听,更新数据方式通常的做法是vm.set('property', value)。
#脏值检查(angular.js)
是通过脏值检测的方式比对数据是否有变更,来决定是否更新视图,最简单的方式就是通过
setInterval() 定时轮询检测数据变动,angular只有在指定的事件触发时进入脏值检测,大致如下:
-
- DOM事件,譬如用户输入文本,点击按钮等。( ng-click )
- XHR响应事件 ( $http )
- 浏览器Location变更事件 ( $location )
- Timer事件( $timeout , $interval )
- 执行 $digest() 或 $apply()
#数据劫持(vue.js)
数据劫持则是采用数据劫持结合发布者-订阅者模式的方式,通过
Object.defineProperty()来劫持各个属性的
setter,
getter,在数据变动时发布消息给订阅者,触发相应的监听回调。
要实现mvvm的双向绑定,就必须要实现以下几点:
-
-
- 实现一个数据监听器Observer,能够对数据对象的所有属性进行监听,如有
变动可拿到最新值并通知订阅者
-
-
- 实现一个指令解析器Compile,对每个元素节点的指令进行扫描和解析,根据指
令模板替换数据,以及绑定相应的更新函数
-
-
- 实现一个Watcher,作为连接Observer和Compile的桥梁,能够订阅并收到每个
属性变动的通知,执行指令绑定的相应回调函数,从而更新视图
上述流程如图所示:
https://github.com/berwin/Blog/issues/18
在这张图中,我们可以看到 Vue 的模板编译是在 $mount 的过程中进行的,在 $mount 的时候执行了 compile 这个方法来将 template 里的内容转换成真正的 HTML 代码。complie 之后执行的事情也蛮重要的,这个我们留到最后再说。complie 最终生成 render 函数,等待调用。这个方法分为三步:
-
- parse 函数解析 template
- optimize 函数优化静态内容
- generate 函数创建 render 函数字符串
Virtual DOM是在MVVM 框架的基础上发展起来的。
MVVM
Virtual DOM 概况来讲,就是在数据和真实 DOM 之间建立了一层缓冲。对于开发者而言,数据变化了就调用 React 的渲染方法,而 React 并不是直接得到新的 DOM 进行替换,而是先生成 Virtual DOM,与上一次渲染得到的 Virtual DOM 进行比对,在渲染得到的 Virtual DOM 上发现变化,然后将变化的地方更新到真实 DOM 上。
React 基于 Virtual DOM 的数据更新与UI同步机制:
初始渲染时,首先将数据渲染为 Virtual DOM,然后由 Virtual DOM 生成 DOM。
数据更新时,渲染得到新的 Virtual DOM,与上一次得到的 Virtual DOM 进行 diff,得到所有需要在 DOM 上进行的变更,然后在 patch 过程中应用到 DOM 上实现UI的同步更新。
下面是通过源码来理解virtual-dom:
https://github.com/DDFE/DDFE-blog/issues/17
https://github.com/DDFE/DDFE-blog/issues/18
四.Vuex
Vuex是专门为Vue.js设计的集中式状态管理模式,它借鉴了Flux和Redux的设计思想,但简化了概念,并采用了一种能更好发挥Vue.js数据响应机制而专门设计的实现。
什么是状态管理模式?
-
- 状态自管理应用包含以下几个部分:
- state,驱动应用的数据源。
- view,以声明方式将state映射到视图;
- actions,响应在view上的用户输入导致的状态变化。
- 以下
是一个表示“单向数据流”理念的极简示意:
但是,当我们的应用遇到多组件共享状态时,单向数据流的简洁性很容易被破坏:
-
- 多个视图依赖于同一状态。
- 来自不同视图的行为需要变更同一状态。
对于问题一,传参的方法对于多层嵌套的组件将会非常繁琐,并且对于兄弟组件间的状态传递无能为力。对于问题二,我们经常会采用父子组件直接引用或者通过事件来变更和同步状态的多份拷贝。以上的这些模式非常脆弱,通常导致无法维护的代码。
因此,我们为什么不把组件的共享状态抽取出来,以一个全局单例模式管理呢?在这种模式下,我们的组件树构成了一个巨大的“视图”,不管在树的哪个位置,任何组件都能获取状态或者触发行为!
另外,通过定义和隔离状态管理中的各种概念并强制遵守一定的规则,我们的代码将会变得更结构化且易维护。
这就是Vuex背后的基本思想,借鉴了Flux、Redux和The Elm Architecture。与其他模式不同的是,Vuex是专门为Vue.js设计的状态管理库,以利用Vue.js的细粒度数据响应机制来进行高效的状态更新。
虽然Vuex可以帮助我们管理共享状态,但也附带了更多的概念和框架。这需要对短期和长期效益进行权衡。
如果不打算开发大型单页应用,使用Vuex可能是繁琐和冗余的。如果需要构建一个中大型单页应用,Vuex将会成为自然而然的选择。
下面是Vuex学习的摘要:
http://note.youdao.com/noteshare?id=633a890ab529bb9eb7e0ea6f5337a6a9
五.其它前端框架的对比
React 和 Vue 有许多相似之处,它们都有:
-
- 使用 Virtual DOM
- 提供了响应式 (Reactive) 和组件化 (Composable) 的视图组件。
- 将注意力集中保持在核心库,而将其他功能如路由和全局状态管理交给相关的库。
React 也有比 Vue 更好的地方,比如更丰富的生态系统。
React 和 Vue 都是非常快的,所以速度并不是在它们之中做选择的决定性因素。对于具体的数据表现,可以参考下图。
在Rect中,一切都是JavaScript。不仅仅是HTML可以用JSX来表示,现在越来越多地将CSS也纳入到JavaScript中来处理。
使用 JSX 的渲染函数有下面这些优势:
-
- 你可以使用完整的编程语言 JavaScript 功能来构建你的视图页面。比如你可以使用临时变量、JS 自带的流程控制、以及直接引用当前 JS 作用域中的值等等。
- 开发工具对 JSX 的支持相比于现有可用的其他 Vue 模板还是比较先进的 (比如,linting、类型检查、编辑器的自动完成)。
Vue中也提供了渲染函数,也支持JSX。但是Vue默认推荐的还是模板Templates。因为不熟悉JS的人去学习使用JSX需要额外的成本,而熟悉Templates的人学习Vue的模板语法会容易一些。
Vue和React都提供了强大的路由来应对大型应用。在React社区中状态管理非常有创新比如Flux、Redux,而这些状态管理模式可以非常容易的集成在Vue应用中。在Vue中,Vuex是状态管理的一种继承。两者另一个重要差异是,Vue 的路由库和状态管理库都是由官方维护支持且与核心库同步更新的。React 则是选择把这些问题交给社区维护,因此创建了一个更分散的生态系统。但相对的,React 的生态系统相比 Vue 更加繁荣。
另外,Vue提供了Vue-cli脚手架,能非常容易地构建项目,但是React的create-react-app在这方面还存在一些局限。
Vue的一些语法和AngularJS很相似,因为AngularJS是Vue早期开发的灵感来源。然而,AngularJS中存在的许多问题在Vue中已经得到了解决。
在API与设计两方面上Vue都比AngularJS简单得多,因此可以快速地掌握它的全部特性并投入开发。
Vue.js 是一个更加灵活开放的解决方案。它允许你以希望的方式组织应用程序,而不是在任何时候都必须遵循 AngularJS 制定的规则。
在 Vue 中指令和组件分得更清晰。指令只封装 DOM 操作,而组件代表一个自给自足的独立单元——有自己的视图和数据逻辑。在 AngularJS 中,每件事都由指令来做,而组件只是一种特殊的指令。
Vue 有更好的性能,并且非常非常容易优化,因为它不使用脏检查。
在 AngularJS 中,当 watcher 越来越多时会变得越来越慢,因为作用域内的每一次变化,所有 watcher 都要重新计算。并且,如果一些 watcher 触发另一个更新,脏检查循环 (digest cycle) 可能要运行多次。AngularJS 用户常常要使用深奥的技术,以解决脏检查循环的问题。有时没有简单的办法来优化有大量 watcher 的作用域。
Vue 则根本没有这个问题,因为它使用基于依赖追踪的观察系统并且异步队列更新,所有的数据变化都是独立触发,除非它们之间有明确的依赖关系。
Angular必须使用TypeScript来开发,因为它的文档和学习资料几乎都是面向TS的。TS 有很多好处——静态类型检查在大规模的应用中非常有用,同时对于 Java 和 C# 背景的开发者也是非常提升开发效率的。然而,并不是所有人都想用 TS——在中小型规模的项目中,引入 TS 可能并不会带来太多明显的优势。在这些情况下,用 Vue 会是更好的选择,因为在不用 TS 的情况下使用 Angular 会很有挑战性。
Vue 相比于 Angular 更加灵活,Vue 官方提供了构建工具来协助你构建项目,但它并不限制你去如何组织你的应用代码。
Angular 的学习曲线是非常陡峭的——作为一个框架,它的 API 面积比起 Vue 要大得多,因此需要理解更多的概念才能开始有效率地工作。当然,Angular 本身的复杂度是因为它的设计目标就是只针对大型的复杂应用;但不可否认的是,这也使得它对于经验不甚丰富的开发者相当的不友好。
六:参考资料
https://blog.csdn.net/fengyinchao/article/details/53518693
https://segmentfault.com/a/1190000008010666
https://segmentfault.com/a/1190000006599500
https://segmentfault.com/a/1190000012922342
https://cn.vuejs.org/v2/guide/comparison.html
https://www.stefankrause.net/js-frameworks-benchmark7/table.html