前端框架学习总结之Angular、React与Vue的比较详解


Posted in Javascript onMarch 14, 2017

近几年前端的技术发展很快,细分下来,主要可以分成四个方面:

      1.开发语言技术,主要是ES6&7,coffeescript,typescript等;

      2.开发框架,如Angular,React,Vue.js,Angular2等;

      3.开发工具的丰富和前端工程化,像Grunt,Gulp,Webpack,npm,eslint,mocha这些技术;

      4.前端开发范围的扩展,如服务端的nodejs,express,koa,meteor,GraphQL;移动端和跨平台的PhoneGap,ionic,ReactNative,Weex;计算机图形学和3维建模领域的WebGL(three.js等);可视化与数据分析领域的d3.js等;包括浏览器不断开放的更多新特性和接口比如svg,canvas,蓝牙,电池,本地存储,service worker,Houdini等新的API能力,以及像WASM这样的底层优化技术;

就开发框架这块,Angular(1&2),React,Vue目前占据着主流地位而且会相持比较长的一段时间,所以这里对比一下这三门技术,以便之后的技术选型。

一、数据流

数据绑定

Angular 使用双向绑定即:界面的操作能实时反映到数据,数据的变更能实时展现到界面。

实现原理:

$scope变量中使用脏值检查来实现。像ember.js是基于setter,getter的观测机制,

$scope.$watch函数,监视一个变量的变化。函数有三参数,”要观察什么”,”在变化时要发生什么”,以及你要监视的是一个变量还是一个对象。

使用ng-model时,你可以使用双向数据绑定。

使用$scope.$watch(视图到模型)以及$scope.$apply(模型到视图),还有$scope.$digest

调用$scope.$watch时只为它传递了一个参数,无论作用域中的什么东西发生了变化,这个函数都会被调用。在ng-model中,这个函数被用来检查模型和视图有没有同步,如果没有同步,它将会使用新值来更新模型数据。

双向绑定的三个重要方法:

$scope.$apply()

$scope.$digest()

$scope.$watch()

在AngularJS双向绑定中,有2个很重要的概念叫做dirty check,digest loop,dirty check(脏检测)是用来检查绑定的scope中的对象的状态的,例如,在js里创建了一个对象,并且把这个对象绑定在scope下,这样这个对象就处于digest loop中,loop通过遍历这些对象来发现他们是否改变,如果改变就会调用相应的处理方法来实现双向绑定

Vue 也支持双向绑定,默认为单向绑定,数据从父组件单向传给子组件。在大型应用中使用单向绑定让数据流易于理解。

脏检测的利弊

和ember.js等技术的getter/setter观测机制相比(优):

getter/setter当每次对DOM产生变更,它都要修改DOM树的结构,性能影响大,Angular会把批量操作延时到一次更新,性能相对较好。

和Vue相比(劣):

Vue.js 有更好的性能,并且非常非常容易优化,因为它不使用脏检查。Angular,当 watcher 越来越多时会变得越来越慢,因为作用域内的每一次变化,所有 watcher 都要重新计算。并且,如果一些 watcher 触发另一个更新,脏检查循环(digest cycle)可能要运行多次。 Angular 用户常常要使用深奥的技术,以解决脏检查循环的问题。有时没有简单的办法来优化有大量 watcher 的作用域。Vue.js 则根本没有这个问题,因为它使用基于依赖追踪的观察系统并且异步列队更新,所有的数据变化都是独立地触发,除非它们之间有明确的依赖关系。唯一需要做的优化是在 v-for 上使用 track-by。

React-单向数据流

MVVM流的Angular和Vue,都是通过类似模板的语法,描述界面状态与数据的绑定关系,然后通过内部转换,把这个结构建立起来,当界面发生变化的时候,按照配置规则去更新相应的数据,然后,再根据配置好的规则去,从数据更新界面状态。

React推崇的是函数式编程和单向数据流:给定原始界面(或数据),施加一个变化,就能推导出另外一个状态(界面或者数据的更新)。

React和Vue都可以配合Redux来管理状态数据。

二、视图渲染

Angular1

AngularJS的工作原理是:HTML模板将会被浏览器解析到DOM中, DOM结构成为AngularJS编译器的输入。AngularJS将会遍历DOM模板, 来生成相应的NG指令,所有的指令都负责针对view(即HTML中的ng-model)来设置数据绑定。因此, NG框架是在DOM加载完成之后, 才开始起作用的。

React

React 的渲染建立在 Virtual DOM 上——一种在内存中描述 DOM 树状态的数据结构。当状态发生变化时,React 重新渲染 Virtual DOM,比较计算之后给真实 DOM 打补丁。

Virtual DOM 提供了函数式的方法描述视图,它不使用数据观察机制,每次更新都会重新渲染整个应用,因此从定义上保证了视图与数据的同步。它也开辟了 JavaScript 同构应用的可能性。

在超大量数据的首屏渲染速度上,React 有一定优势,因为 Vue 的渲染机制启动时候要做的工作比较多,而且 React 支持服务端渲染。

React 的 Virtual DOM 也需要优化。复杂的应用里可以选择 1. 手动添加 shouldComponentUpdate 来避免不需要的 vdom re-render;2. Components 尽可能都用 pureRenderMixin,然后采用 Flux 结构 + Immutable.js。其实也不是那么简单的。相比之下,Vue 由于采用依赖追踪,默认就是优化状态:动了多少数据,就触发多少更新,不多也不少。

React 和 Angular 2 都有服务端渲染和原生渲染的功能。

Vue.js 不使用 Virtual DOM 而是使用真实 DOM 作为模板,数据绑定到真实节点。Vue.js 的应用环境必须提供 DOM。Vue.js 有时性能会比 React 好**,而且几乎不用手工优化。

三、性能与优化

性能方面,这几个主流框架都应该可以轻松应付大部分常见场景的性能需求,区别在于可优化性和优化对于开发体验的影响。Vue 的话需要加好 track-by 。React 需要 shouldComponentUpdate 或者全面 Immutable,Angular 2 需要手动指定 change detection strategy。从整体趋势上来说,浏览器和手机还会越变越快,框架本身的渲染性能在整个前端性能优化体系中,会渐渐淡化,更多的优化点还是在构建方式、缓存、图片加载、网络链路、HTTP/2 等方面。

四、模块化与组件化

Angular1 -> Angular2

Angular1使用依赖注入来解决模块之间的依赖问题,模块几乎都依赖于注入容器以及其他相关功能。不是异步加载的,根据依赖列出第一次加载所需的所有依赖。

可以配合类似于Require.js来实现异步加载,懒加载(按需加载)则是借助于 ocLazyLoad 方式的解决方案,但是理想情况下应该是本地框架会更易懂。

Angular2使用ES6的module来定义模块,也考虑了动态加载的需求。

Vue

Vue中指令和组件分得更清晰。指令只封装 DOM 操作,而组件代表一个自给自足的独立单元 —— 有自己的视图和数据逻辑**。在 Angular1 中两者有不少相混的地方。

React

一个 React 应用就是构建在 React 组件之上的。

组件有两个核心概念:props,state。

一个组件就是通过这两个属性的值在 render 方法里面生成这个组件对应的 HTML 结构。

传统的 MVC 是将模板放在其他地方,比如 script 标签或者模板文件,再在 JS 中通过某种手段引用模板。按这种思路,想想多少次我们面对四处分散的模板片段不知所措?纠结模板引擎,纠结模板存放位置,纠结如何引用模板。

React 认为组件才是王道,而组件是和模板紧密关联的,组件模板和组件逻辑分离让问题复杂化了。所以就有了 JSX 这种语法,就是为了把 HTML 模板直接嵌入到 JS 代码里面,这样就做到了模板和组件关联,但是 JS 不支持这种包含 HTML 的语法,所以需要通过工具将 JSX 编译输出成 JS 代码才能使用(可以进行跨平台开发的依据,通过不同的解释器解释成不同平台上运行的代码,由此可以有RN和React开发桌面客户端)。

五、语法与代码风格

React,Vue,Angular2都支持ES6,Angular2官方拥抱了TypeScript这种 JavaScript 风格。

React 以 JavaScript 为中心,Angular 2 依然保留以 HTML 为中心。Angular 2 将 “JS” 嵌入 HTML。React 将 “HTML” 嵌入 JS。Angular 2 沿用了 Angular 1 试图让 HTML 更强大的方式。

React 推荐的做法是 JSX + inline style,也就是把 HTML 和 CSS 全都整进 JavaScript 了。Vue 的默认 API 是以简单易上手为目标,但是进阶之后推荐的是使用 webpack + vue-loader 的单文件组件格式(template,script,style写在一个vue文件里作为一个组件)

总结

好了,以上就是这篇文章的全部内容了,本文的话题实际上很大,需要对Angular,React和Vue三门技术有足够深入的了解,所以难免有很多总结的不全或者不够深入的地方,后续我会不断完善和修改。希望本文的内容对大家的学习或者工作能带来一定的帮助。

Javascript 相关文章推荐
提高网站信任度的技巧
Oct 17 Javascript
根据邮箱的域名跳转到相应的登录页面的代码
Feb 27 Javascript
阻止子元素继承父元素事件具体思路及实现
May 02 Javascript
jQuery判断checkbox(复选框)是否被选中以及全选、反选实现代码
Feb 21 Javascript
javascript数据类型示例分享
Jan 19 Javascript
javascript中offset、client、scroll的属性总结
Aug 13 Javascript
jQuery添加删除DOM元素方法详解
Jan 18 Javascript
JS采用绝对定位实现回到顶部效果完整实例
Jun 20 Javascript
BootStrap无限级分类(无限极分类封装版)
Aug 26 Javascript
JavaScript 函数模式详解及示例
Sep 07 Javascript
NPM 安装cordova时警告:npm WARN deprecated minimatch@2.0.10: Please update to minimatch 3.0.2 or higher to
Dec 20 Javascript
JSONP跨域请求
Mar 02 Javascript
jQuery ajax实现省市县三级联动
Mar 07 #Javascript
Javascript前端经典的面试题及答案
Mar 14 #Javascript
layer弹出层框架alert与msg详解
Mar 14 #Javascript
微信小程序 仿猫眼实现实例代码
Mar 14 #Javascript
利用js定义一个导航条菜单
Mar 14 #Javascript
微信小程序 跳转传参数与传对象详解及实例代码
Mar 14 #Javascript
使用BootStrap实现标签切换原理解析
Mar 14 #Javascript
You might like
深入研究PHP中的preg_replace和代码执行
2018/08/15 PHP
关于Laravel参数验证的一些疑与惑
2019/11/19 PHP
jQuery实现图片信息的浮动显示实例代码
2013/08/28 Javascript
JS实现点击链接取消跳转效果的方法
2014/01/24 Javascript
javascript连续赋值问题
2015/07/08 Javascript
Jquery跨域获得Json的简单实例
2016/05/18 Javascript
深入浅析knockout源码分析之订阅
2016/07/12 Javascript
利用jquery获取select下拉框的值
2016/11/23 Javascript
Vue.js中的图片引用路径的方式
2017/07/28 Javascript
jquery 键盘事件的使用方法详解
2017/09/13 jQuery
vue的无缝滚动组件vue-seamless-scroll实例
2017/12/18 Javascript
在vue中封装可复用的组件方法
2018/03/01 Javascript
10分钟上手vue-cli 3.0 入门介绍
2018/04/04 Javascript
JavaScript插入排序算法原理与实现方法示例
2018/08/06 Javascript
微信小程序框架wepy之动态控制类名
2018/09/14 Javascript
微信小程序中的店铺评分组件及vue中用svg实现的评分显示组件
2018/11/16 Javascript
Vue使用NProgress进度条的方法
2019/09/21 Javascript
如何利用javascript接收json信息并进行处理
2020/08/06 Javascript
vue绑定class的三种方法
2020/12/24 Vue.js
[01:13:51]TNC vs Serenity 2018国际邀请赛小组赛BO2 第二场 8.18
2018/08/19 DOTA
[56:13]DOTA2-DPC中国联赛定级赛 LBZS vs Phoenix BO3第一场 1月10日
2021/03/11 DOTA
跟老齐学Python之dict()的操作方法
2014/09/24 Python
python实现矩阵乘法的方法
2015/06/28 Python
Python下应用opencv 实现人脸检测功能
2019/10/24 Python
Python selenium的基本使用方法分析
2019/12/21 Python
Pytorch在NLP中的简单应用详解
2020/01/08 Python
Python3.7 读取音频根据文件名生成脚本的代码
2020/04/07 Python
python SOCKET编程基础入门
2021/02/27 Python
总结30个CSS3选择器
2017/04/13 HTML / CSS
基于HTML5的WebSocket的实例代码
2018/08/15 HTML / CSS
国际知名军事风格休闲装品牌:Alpha Industries(阿尔法工业)
2017/05/24 全球购物
优秀女职工事迹材料
2014/02/06 职场文书
保险公司年会主持词
2014/03/22 职场文书
2014流动人口计划生育工作总结
2014/12/20 职场文书
幼儿园小班个人总结
2015/02/12 职场文书
结婚当天新郎保证书
2015/05/08 职场文书