2017前端框架何去何从

>这篇随笔将从 AngularJS ReactJS Polymer
这一个流行的框架动手,分析前端框架在这几年更上一层楼中的关键技术点,作为2015前端技术选型的参阅。摘要:

– 初体验

  • 技巧特色
  • 组件化
  • 使用架构

### 总结

**1. 初体验**
拿TODO来作为引子好了.
       
 ![](//upload-images.jianshu.io/upload_images/8373224-4e10488b2196f18d.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
Angular 的实现
![](//upload-images.jianshu.io/upload_images/8373224-5966342b1a65597b.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
React的实现(非flux架构)
![](//upload-images.jianshu.io/upload_images/8373224-fdd1c5436dfee33e.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
Polymer的实现
![](//upload-images.jianshu.io/upload_images/8373224-e39a00c0f65ac2e8.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
三者共同相比
![](//upload-images.jianshu.io/upload_images/8373224-2e20982ca8e05655.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
在Angular中有controller和component的概念是分离的,而react和polymer中唯有component的定义。
实际三者在最简单易行的施用情况下差异并不大,Angular和polymer模板和代码分离的点子更接近于传统的前端做法,而React写法更像后端渲染。关于读书和拔取基金的何人高什么人低得问题尚未什么样好争持的,在MVVM已经风靡了这么久的情事下,三者入门门槛都差不多,但要用好都急需深切内部的运行机制才行。

**2. 技能特色**

其实所谓的MVVM框架的关键技术就一个:数据与视图的绑定。在Angular/polymer/knockout/vue/avalon
中,这项技术的贯彻又足以拆分成多少个关键点:模板分析和数目监测。
模板分析的显要目标是对 {{title}}
这样的标志举办采访。收集完成将来生成一个视图更新函数,在函数内部保存着这么些符号所在的Dom片段和连锁的多少名称,函数被调用时会去重新取多少名称对应的多寡(或者由外部将相应的数据作为参数传入),然后更新dom片段。这样就落实了视图的换代。一般框架会在启动时就将模板分析完,生成对应的视图更新函数。当数码更新的时候,就调用那一个立异函数来更新视图,那么问题来了,怎样检测数据的改变?
knockout/angular/avalon代表了两种方案:

– 使用自定义的数据对象及其指定的get和set函数。例如你不得不使用
user.set(“name”,”john”)来给user对象的name属性赋值,因为这样它才能在set函数中通晓修改了如何性质,并且只调用相应的视图更新函数。这种格局不太爽的地点在于改变了本来面目的JS对象使用的不二法门。

  • 运用 Object.defineProperty
    的get和set函数来检测对象属性的转移,本质上和上种没有什么样界别。不过它有一个弱点,就是无力回天检测新增的或删除的性质。有的框架是通过Object.observe来补充这种方案的,然则Object.observe
    近期也只有chrome辅助。这种措施改善了上边的支付体验,你可以像使用原生JS对象一样来操作你的数据。然则在实现上相比较复杂。
  • dirty
    check。这是angular正在选用的建制,它并无法像前二种同等只要数据发生变化立刻触发更新回调。而是必须在调用了angular提供的部分主意,或者触发了页面上行使了ng-click等的因素上的事件后才会接触。这么些触发时机是angular内部就曾经落实了的,所以您几乎感觉不到。这种方法被称作”dirty”的因由是,它保存了具备属性上五回的值,检测是透过遍历对象的所有属性,相比它和上五回值是否一致来促成的。假使是深层对象的话,它会层层遍历。这种检测方法组成了地方二种的优势,可是对性能造成了负责。

由来,四个首要技术点都已讲精晓,用一张图来回顾一下
![](//upload-images.jianshu.io/upload_images/8373224-7c3f8defccefd595.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
而在React中则相对简单,React用的是相仿于重绘的体制,当接触了 setState
之后,就全盘重复渲染(并非登时触发,中间有相近于缓存的特性提高机制)。这看起来相比较前面的方案大概粗暴,不过却因为virtual
dom的实现化腐朽为神奇了。virtual
dom指的是React内部用来效仿真实dom的一种多少对象。当再一次渲染时,实际上是先生成这样virtual
dom,然后将其和上三次的virtual
dom举行相比,找出差异,最终由react在真正的dom上更新有差距的一些就够了。因为virtual
dom始终在内存中,真实的dom操作相当少,而眼前的两种框架在改进视图时通常会有大气的dom操作,由此react在性质上大大超越前一种档次的框架。同时也因为virtual
dom依然是明媒正娶的
js对象,所以使得”服务端渲染”也改为可能。值得注意的是,固然React本身并不会像前面的框架一样浓厚的去检测数据的哪一部分生出了变通,不过可以通过官方提供的addon
和immutable.js来进一步提升这一块的性质。
(web前端学习互换群:328058344 禁止闲聊,非喜勿进!)

**3. 组件化**

在组件化的取向上 react 和任何三种框架几乎已经风流云散了。从
angular2.0的宏图和新出的 aurelia 等框架中得以见见我们都在品味往
webcomponent
靠近。polymer号称下个版本代码将大幅削减,这无非是因为浏览器将实现正式了。靠近
webcomponent 的利益在于任何一个框架都将不再封闭,以 custom
element作为接口层,能落实生态圈的齐心协力。即便 react 也有封装成 custom
element的方案,不过 react 并从未很好的调用其他框架生成的 custom element
的方案。”像使用原生dom元素一样采纳custom
element”的组件使用模式意味着尊重原生的dom使用形式,包括dom的事件等等。那和react”不操作实际dom”的底子已经方向相反了。
react和其他框架的争论其实近来看来并无优劣之分,因为webcomponent近期除了chrome以外其他浏览器协助如故不圆满。另外考虑到相当国情的话,大公司的出品如故要直面IE8。不幸的是眼下polymer的polyfill最低也只到IE9。而React能无痛帮助IE8。再考虑到移动端的浏览器意况的话,也是行使react的技能障碍远小于webcomponent。
一体化来看,webcomponent肯定会是主旋律,并且将推向各种框架变得越来越开放,更易相互融合。而react也仍将延续看重自己在贯彻上的优势继续走下去。也许未来在这中档又将诞生新东西。
暂时抛开react和webcomponent。我们后续长远五个近年来谈论得很少不过却很首要的题材(下边探讨的组件问题皆以封装成custom
element为根基):

  • 怎么能把组件变得更易重用? 具体一点:
  • 自己在用某个组件时需要重新调整一下零部件里面元素的一一怎么做?
  • 自我想要去掉组件里面某一个元素咋办?

– 咋样把组件变得更易扩充? 具体一点:

  • 业务方不断要求给组件加效果肿么办?

本着第一个问题,我所在的团社团近期指出一个称为”模板复写”的条条框框,这多少个规则又分为”完全重写”和”部分重写”二种规则:
![](//upload-images.jianshu.io/upload_images/8373224-fa4f09d37ea116cc.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
 
**一部分重写**

![](//upload-images.jianshu.io/upload_images/8373224-3cdbf825598ef138.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
那种方案已在angular中实现。并且在组件重用率高的体系中早就证实异常实用。但它也有瑕疵,缺陷在于你无法不知道当前组件的实现形式和原有模板才能复写。

第二个问题,可以用一种名叫”共享功用域”的点子来化解。例如地方的例子中story没有呈现like数量,现在要体现出来。常规方案有二种:

– 改组件,在组件中加进那么些功用。


给组件扩充api用于获取总计数据,同时在总计数据暴发变化时抛出事件通报外部。

第一种方案或者碰着的问题是当再次发生变化,例如总括数据不要突显在组件里面了。就得继续改成第二种方案。
第两种方案或者遇见的问题是可能无休止有新的急需提议来,最后不得不把每一个内部意况都透流露来,每一个操作过程都抛出事件。

“效能域共享”共享的方案是: 通过在一个例外标记 “import-to”
将某一段外部html引入到某个组件中去一起插足”模板解析”和”数据绑定”,当成功时再放回原来的职务。这样这么些外部html就能博拿到零部件内部任何动静和数目了。这种方案看起来有点像hack,但实质上只是换了一种艺术来了然组件:组件分成两个部分,一是数据,二是视图。视图理论上应该只受到它的逻辑是不是丰裕内聚的束缚,而不应当受到它的子元素是否位于一起的羁绊。不过当前我们恰好使用了dom作为视图的功底,所以视图受到html结构的自律,这多少个约束是不成立的。我们来用图比较一下使用”效能域共享”前后的现象:

![](//upload-images.jianshu.io/upload_images/8373224-cddbe4ace31d7d1e.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

自然,这种方案的症结如故是您必须精晓组件的切实可行落实。但这并不是一个不足战胜的弱项,我们看下aurelia的筹划,它将template等等紧要部分都规划成了可插拔的花样,这种结构意味着以后有可能实现一种通用的沙盘语法来促成上述多少个功能。这样就不再和底部耦合。

**4. 拔取架构**

应用架构的限制太广,大家那里只谈谈这个早已很好地组件化了的采取,或者是没组件化可是有明确层级细分的施用。我们以React
对应的 FLUX 为切入点。 

![](//upload-images.jianshu.io/upload_images/8373224-5b9215333e5428dc.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

咱俩再来结合facebook的官方FLUX代码示例来探望每个部分:

![](//upload-images.jianshu.io/upload_images/8373224-a4d8d0fb2c5ff03a.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

facebook在介绍FLUX的时候的重大观点是”MVC增加性不够,FLUX可扩大性高”。暂且不去研商FLUX与MVC的界别,
我们先来它是咋样扩大的,从地点的代码中得以看出,ACTION不只是一个界面上的点击事件所发出的,ajax请求、甚至一个先导化过程都得以生出动作,”动作”只是一个空洞。动作将传递给dispatcher,有dispatcher在去触发store注册的回调。你或许会想,从这多少个dispatcher实际上什么也没干,这和自我直接定义一个方法,触发事件就径直调用这么些形式有如何界别?区别在于,当使用扩展效益、举行扩大时,应用可能有两个部分要一同对同一个action举办响应,并且不同的协同部分或者在举办顺序上有严谨的次序之分。

> 举个例证

假诺我要对地点的TODO扩大一个”总结区块”,淌假若观念的MVC写法,你或许要新增一个statisticModel,然后在controller中的createTODO、deleteTODO中加进代码来操作这些新的statisticModel。而FLUX不用修改已部分任何代码,只需要写新的store,并登记一些回调到createAction、deleteAction中就够了。所以可以看做是将MVC中的
“C主动操作M” 反转成 “M来决定什么时候运行”(当然这种景色也就从不C了),
但更好的是知道成是一种”事件系统”的变种。这就是它和MVC的分别。严俊来说
FLUX
并不能够算是facebook”发明”出来的,这样的模子在很多事件驱动的后端框架中很广泛,如[zero](https://github.com/sskyy/zero)、\[yii\](http://www.yiiframework.com/),只不过拿到前端来作为应用架构时比较新颖。

FLUX是当下低度推荐的应用架构模式,它并从未强制行使的库或者框架,所以并不局限于react,在angular、polymer中一样能自由实现。特别是眼下angular、polymer中的应用开发并不曾一种拔取架构的特级实践。angular中的模块化既没有异步加载也平昔不功效域隔离的功用,实际行使时很鸡肋。不过angular中的倚重注入、filter、service的统筹丰硕健全,如若再能加上FLUX的架构的话,威力不容小视。对polymer来说情形更简便易行,应为polymer近年来只考虑到element这一层,所以上层的采纳架构可以肆意实现。
值得补充的是,FLUX中的store,dispatcher可以更好地加强一下。store可以应用部分电动帮忙REST的库来简化开发,dispatcher可以接纳援助自定义顺序等高等的事件代理实现。

**5. 总结**

2015将是前者框架相互借鉴相互融合的一年,随着webcomponent的出生,我们都在像正规靠近。提前储备这方面的技能一定没有问题。再浓厚到框架的技术细节中,我们看出在”渲染机制”、”数据绑定”、”组件化”、”模块化”那些关键技术点中各个框架中都有异常优良的实现,值得深入学习。React异军突起,也推荐持续关注,特别是在”应用架构”上,FLUX确实在任何业界起到了启示的职能,相信会愈发流行,并且有进一步多实现格局。

相关文章