1.4 Vue与Angular

无论在代码体积和性能上面,Vue都比Angular1、Angular 2表现得优异许多,这里不再赘述。笔者选择了以下几个方面来对比分析Vue和Angular的表现。

1.4.1 模板语法

Vue的许多语法和Angular十分相似,可以认为Angular是Vue的灵感之源。因为尤雨溪当时在Google创意实验室,使用的就是Google主推的Angular框架。但是,随着使用程度不断加深,尤感觉Angular十分笨重,因此这才创造了Vue。在Vue的诞生过程中,有很多地方都借鉴了Angular的语法习惯。

Angular 2语法:

     <input type="text" [(ngModel)]="name"/>
     <button (click)="onSave($event)">Save</button>
     <ul>
       <li *ngFor="letheroofheroes" [title]="hero.name" (click)="delete
     (hero)">{{hero.name}}</li>
     </ul>
     <form #heroForm (ngSubmit)="submit()"></form>

Vue语法:

     <input type="text" v-model="name"/>
     <button v-on:click="onSave($event)">Save</button>
     <ul>
        <li v-for="heroinheroes" v-bind:title="hero.name" v-on:click="delete
     (hero)">{{hero.name}}</li>
     </ul>
     <form ref="heroForm" v-on:submit="submit()"></form>

1.4.2 脏检测

Vue与Angular 1相比最大的区别在于没有脏检测机制。在Angular 1中存在多个watcher,当watcher越来越多时,检测耗时会越来越长。因为作用域中每发生一次变化,所有watcher都要重新计算,而一些watcher在计算之后可能又会导致新的变化,并引发所有watcher重新计算,从而进入一种无限循环的脏检测。

Angular 1的处理方式是设置循环上限,比如10次,当循环达到10次,即中止循环。显然,这种脏检测机制性能十分低下、耗时长,并不适合大型Web应用。

Vue的处理方式则是全局只设置一个watcher,用这一个watcher来记录和更新一组关联对象的值,从而回避了脏检测的问题。

有意思的是,Vue最初是参考Angular的,而Angular 2则借鉴了Vue的机制,采用相似的设计来解决脏检测存在的问题。

1.4.3 双向数据绑定

轻、重量级框架划分的标准是,是否过分参与系统结构级的架构和功能上的伸缩拓展。和Vue、React这样的轻量级框架相比,Angular在单向数据流的视图渲染、事件绑定之外,还参与了View对Model层的数据更新,即双向数据绑定。显然,它是一个重量级框架。

在单向数据绑定中,视图模板和动态数据被渲染成网页后,数据流即中止,如图1.12所示。之后,由ViewModel接手与View层的数据绑定。View层不可以直接修改Model层的数据,如果需要修改Model层的数据,则由ViewModel发起请求,这中间存在ViewModel和Model之间的数据同步传输。

图1.12 单向数据绑定

然而,在双向数据绑定中,Model和View始终建立着联系,Model层的数据也一直保持着真实的状态,如图1.13所示。

图1.13 双向数据绑定

1.4.4 学习曲线

最后一点,广为人知且津津乐道的是,Angular的学习曲线十分陡峭,初学者可能会有一种坐过山车的感觉。不过,笔者在2016年,接触过一个使用Angular 1进行开发的项目,当时感觉坡度是有的,但没有那么夸张,也可能是因为应用比较浅吧。

Vue的学习曲线则较为平缓,在Ember、Knockout、Angular、React等前辈踏平的道路上,Vue有更多趋于成熟的最佳实践可以拿来使用,也有更多的经验教训可以参考,从而设计出更简便的API来实现更复杂的功能。同时,这也有效降低了团队开发成本,并使得大型Web项目的构建变得更加容易。