Home - RLwu/angular-start GitHub Wiki
Angular for DartWelcome to the Angular2 wiki!
首先,框架间的竞争并不是零和游戏。虽然解决的核心痛点有重合,但适用场景还是有区别。比如 React/Vue 这样以 view layer 为核心,可以灵活选择整体架构和工具链的框架,和 Angular 2 这样大而全一站到底的框架,各有各适合的场景。Vue 因为不需要构建也能直接用,也能用在一些比 React 更轻量的场景中。撇开场景,也有开发风格的偏好问题。有些人用 React 更有效率,有些人用 Vue 更有效率,而 C#/Java 生态圈一大群人会觉得 TypeScript 和 Angular 2 让他们更有效率(详细参考TypeScript语法,对于后台程序员来说能快速入手)。最理想的情况是大家都找到最符合自己场景需求和开发偏好的框架,所以我觉得多框架的并存是合理且有意义的,不太可能出现 Angular 2 火了就没人再用 React/Vue 的情况。
React 和 Angular 2 都有服务端渲染和原生渲染的功能。这两个东西在对此有需求的场景下,是很有吸引力的,但实际上对此有硬需求的场景占多少百分比则是个问题。比如服务端渲染的前提是前端渲染层得用 Node.js 交给『全栈』去做,原生渲染的多端代码复用率会因应用实际需求而变化,制约它们发挥的条件还是不少的,因此这并不会影响 Vue 在整个市场中占有一席之地。另一方面,手淘已经押宝 Weex,也不排除哪天我会搞个 Vue 服务端渲染。
性能方面,这几个主流框架都应该可以轻松应付大部分常见场景的性能需求,区别在于可优化性和优化对于开发体验的影响。这一点上我觉得 Vue 可能是最简单的,加好 track-by 就 ok 了。React 需要 shouldComponentUpdate 或者全面 Immutable,Angular 2 需要手动指定 change detection strategy,都有一定程度的侵入性。但是从整体趋势上来说,浏览器和手机还会越变越快,框架本身的渲染性能在整个前端性能优化体系中,会渐渐淡化,更多的优化点还是在构建方式、缓存、图片加载、网络链路、HTTP/2 等方面。顺道说一句,Angular 2 压缩后的大小是 500 多 kb,在移动场景反正不太敢用。
这方面, Vue最具亲和度的。工具链方面最近刚发布了 vue-cli,1 分钟搞定 webpack 配置。Vue 组件格式只要你会 HTML/CSS/JS 就能写,你要用 coffeescript 或者 less/sass 也没问题。React 的 JSX 是道坎,但跨过去之后会有一定的生产力提升。社区工具丰富,但实在太多,配置工具麻烦。CSS in JS 也不是每个人的菜。Angular 2 目前上手配置也非常麻烦,官方正在写一个 cli,但体验如何要出来了才知道。它推荐的默认语言是 TypeScript,这个对于静态类型爱好者来说是个大优点,配合 WebStorm/VSCode 体验会很不错。
-
React 是目前最成熟也最活跃的,但有一个问题就是过于频繁的方案迭代,几个月前的最佳实践可能明天就变过去式了,而 FaceBook 官方对于最佳实践基本是采取让社区自行发展的态度,因此社区长期处于一个百家争鸣的状态,直到今年下半年才慢慢地开始合流到了 React + react-router + redux 的主流方案,并且这两天也开始讨论工具链的最佳实践。这些东西一旦稳定下来,会进一步巩固 React 的地位。
-
Vue 的社区固然比不上 React,但也不算太小。Gitter 聊天室里有 1300 来号人,国内听说也有几百人的 QQ 群,论坛上也还算有些活跃度。社区组件也在稳步发展:vuejs/awesome-vue · GitHub 当然比起 React 来说还是小巫见大巫,希望 2016 能更进一步。比起 React 来说,Vue 的一个好处就是提供了官方推荐的 Vue + vue-router + vuex + webpack + vue-loader 的全套方案,如果你不想三个月换一套,就跟着官方推荐走;如果自己有想法,那就自己整也没问题。
-
Angular 2 的社区,目前来说基本没有,到现在连文档都没写完呢,也没法有什么生态。更伤的是 ng2 和 ng1 的生态是完全割裂的。2016 年能怎么发展,要看 Google 的社区运营做得如何,但不管怎么说 Google 的影响力在那边,群众基数还是很大的...
这一块 ,在国内有一个制约条件,那就是 IE8,这三个框架里面只有 React 支持 IE8,所以这应该会对 React 在中国的份额有所帮助... 而Angular2.0制约性相对来说会大一些。
两者根本不具有可比性!
嗯!Angular 是框架,React 是类库。所以有人觉得比较这两者没有逻辑性可言。
选择 Angular 还是 React 就像选择直接购买成品电脑还是买零件自己组装一样。
两者的优缺点在这儿都会提及,我会拿 React 语法和组件模型跟 Angular 的语法和组件模型做对比。这就像是拿成品电脑的 CPU 跟零售的 CPU 做对比,没有任何不妥。
- 无选择性疲劳 Angular 是一个完整的框架,本身就提供了比 React 多得多的建议和功能。而要用 React,开发者通常还需要借助别的类库来打造一个真正的应用。比如你可能需要额外的库来处理路由、强制单向数据流、进行 API 调用、做测试以及管理依赖等等。要做的选择和决定太多了,让人很有压力。这也是为什么 React 有那么多的入门套件的原因。
Angular 自带了不少主张,所以能够帮助更快开始,不至于因为要做很多决定而无所适从。这种强制的一致性也能帮助新人更快适应其开发模式,并使得开发者在不同团队间切换更具可行性。
Angular 核心团队拥抱了 TypeScript,这就造成了另一个优势。
- TypeScript = 阳关大道
没错,并非所有人都喜欢 TypeScript,但是 Angular 2 毅然决然地选择了它确实是个巨大的优势。反观 React,网上的各种示例应用令人沮丧地不一致——ES5 和 ES6 的项目基本上各占一半,而且目前存在三种不同的组件声明方式。这无疑给初学者造成了困惑。(Angular 还拥抱了装饰器(decorator)而不是继承(extends)——很多人认为这也是个加分项)。
尽管 Angular 2 并不强制使用 TypeScript,但显然的是,Angular 的核心团队默认在文档中使用 TypeScript。这意味着相关的示例应用和开源项目更有可能保持一致性。Angular 已经提供了非常清晰的关于如何使用 TypeScript 编译器的例子。(目前并非所有人都在拥抱 TypeScript,但正式发布之后,TypeScript 会成为事实上的标准)。这种一致性应该会帮助初学者避免在学习 React 时遇到的疑惑和选择困难。
- 极少的代码变动
2015 年是 JavaScript 疲劳元年,React 可以说是罪魁祸首。而且 React 尚未发布 1.0,所以未来还可能有很多变数。React 生态圈依旧在快速地变动着,尤其是各种 Flux 变种和路由。也就是说,你今天用 React 写的所有东西,都有可能在 React 1.0 正式发布后过时,或者必须进行大量的改动。
相反,Angular 2 是一个对已经成熟完整框架(Angular 1)的重新发明,而且经过仔细、系统的设计。所以 Angular 不大可能在正式发布后要求已有项目进行痛苦的代码变动。Angular 作为一个完整的框架,你在选择它的时候,也会信任其开发团队,相信他们会认真决定框架的未来。而使用 React,一切都需要你自己负责,你要自己整合一大堆开源类库来打造一个完整的应用,类库之间互不相干且变动频繁。这是一个令人沮丧的耗时工作,而且永远没有尽头。
- 广泛的工具支持
后面我会说,我认为 React 的 JSX 是非常耀眼的亮点。然而要使用 JSX,你需要选择支持它的工具。尽管 React 已经足够流行,工具支持不再是什么问题,但诸如 IDE 和 lint 工具等新工具还不大可能很快得到支持。Angular 2 的模版是保存在一个字符串或独立的 HTML 文件中的,所以不要求特殊的工具支持(不过似乎 Angular 字符串模版的智能解析工具已经呼之欲出了)。
- Web Components 友好
Angular 2 还拥抱了 Web Component 标准。简单来说,把 Angular 2 组件转换成原生 Web Components 应该会比 React 组件容易得多。固然 Web Components 的浏览器支持度依然很弱,但长期来看,对 Web Components 友好是很大的优势。
Angular 的实现有其自身的局限和陷阱,这正好让我过渡到对 React 优势的讨论。
现在,让我们看看是什么让 React 如此与众不同。
- JSX
JSX 是一种类似 HTML 的语法,但它实际上会被编译成 JavaScript。将标签与代码混写在同一个文件中意味着输入一个组件的函数或者变量时你将享受到自动补全的福利。而 Angular 基于字符串的模版就相形见绌了:很多编辑器都不会高亮它们(只会显示单色)、只有有限的代码补全支持,并且一直到运行时才会报错。并且,通常你也只能得到很有限的错误提示。不过,Angular 的团队造了一个自己的 HTML 解析器来解决这个问题。(叼叼叼!)
如果你不喜欢 Angular 的字符串模版,你可以把模版移到一个单独的文件里去。不过这样你就回到了我认为的“老样子”:你需要在自己脑袋里记住这两个文件的关联,不但没有代码自动补全,也没有任何编译时检查来协助你。这听起来可能并不算什么……除非你已经爱上了与 React 相伴的日子。在同一个文件中组合组件还能享受编译时的检查,大概是 JSX 最与众不同的地方之一了。
- React 报错清晰快速
当你在 React 的 JSX 中不小心手抖打错时,它并不会被编译。这是一件非常美妙的事情:无论你是忘记闭合了标签还是引用了一个不存在的属性(property),你都可以立刻知道到底是哪一行出错了。JSX 编译器会指出你手抖的具体行号,彻彻底底加速你的开发。
相反,当你在 Angular 2 中不小心敲错了一个变量时,鸦雀无声。Angular 2 并不会在编译时做什么,它会等到运行时才静默报错。它报错得如此之慢,我加载完整个应用然后奇怪为什么我的数据没有显示出来呢?这太不爽了。
- React 以 JavaScript 为中心
终于来了。这才是 React 和 Angular 的根本区别。很不幸,Angular 2 仍然是以 HTML 而非 JavaScript 为中心的。Angular 2 并没有解决它设计上的根本问题:
Angular 2 继续把 “JS” 放到 HTML 里。React 则把 “HTML” 放到 JS 里。
这种分歧带来的影响真是再怎么强调也不为过。它们从根本上影响着开发体验。Angular 以 HTML 为中心的设计留下了巨大的缺陷。JavaScript 远比 HTML 要强大。因此,增强 JavaScript 让其支持标签要比增强 HTML 让其支持逻辑要合理得多。无论如何,HTML 与 JavaScript 都需要某种方式以粘合在一起。React 以 JavaScript 为中心的思路从根本上优于 Angular、Ember、Knockout 这些以 HTML 为中心的思路。
让我们来看看为什么。
- React 以 JavaScript 为中心的设计 = 简约
Angular 2 延续了 Angular 1 试图让 HTML 更加强大的老路子。所以即使是像循环或者条件判断这样的简单任务你也不得不使用 Angular 2 的独特语法来完成。例如,Angular 2 通过两种语法同时提供了单向数据绑定与双向数据绑定,可不幸的是它们实在差得有点多:
{{myVar}} //单向数据绑定 ngModel="myVar" //双向数据绑定 在 React 中,数据绑定语法不取决于数据流的单双向(数据绑定的单双向是在其他地方处理的,不得不说我觉得理应如此)。不管是单向还是双向数据流,绑定语法都是这样的:
{myVar}
Angular 2 的内联母版(inline master templates)使用了这样的语法:
<ul>
<li *ngFor="#hero of heroes">
{{hero.name}}
</li>
</ul>
上面这个代码片段遍历了一组 hero,而我比较关心的几点是:
通过星号来声明一个“母版”实在是太晦涩了
相比上面 Angular 2 的语法,React 的语法可是纯净的 JavaScript (不过我得承认下面的属性 key 是个 React 的私货)
<ul>
{ heroes.map(hero =>
<li key={hero.id}>{hero.name}</li>
)}
</ul>
鉴于 JS 原生支持循环,React JSX 利用 JS 的力量来做到这类事情简直易如反掌,配合 map、filter 能做的还远不止此。
去看看 Angular 2 速查表?那不是 HTML,也不是 JavaScript……这叫 Angular。
读懂 Angular:学一大堆 Angular 特有的语法
读懂 React:学 JavaScript
React 因为语法和概念的简约而与众不同。我们不妨品味下当今流行的 JS 框架/库都是如何实现遍历的:
Ember: {{# each}}
Angular 1: ng-repeat
Angular 2: ngFor
Knockout: data-bind="foreach"
React: 直接用 JS 就好啦 :)
除了 React,所有其它框架都用自己的专有语法重新发明了一个我们在 JavaScript 常见得不能再常见的东西:循环。这大概就是 React 的美妙之处,利用 JavaScript 的力量来处理标签,而不是什么奇怪的新语法。
Angular 2 中的奇怪语法还有点击事件的绑定:
(click)="onSelect(hero)"
相反,React 再一次使用了普通的 JavaScript:
onClick={this.onSelect.bind(this, hero)}
并且,鉴于 React 内建了一个模拟的事件机制(Angular 2 也有),你并不需要去担心使用内联语法声明事件处理器所暗含的性能问题。
为什么要强迫自己满脑子都是一个框架的特殊语法呢?为什么不直接拥抱 JS 的力量?
- 担心框架的大小?
这里是一些常见框架/库压缩后的大小(来源):
- Angular 2: 566k (766k with RxJS)
- Ember: 435k
- Angular 1: 143k
- React + Redux: 139k
列出的都是框架级的、用于浏览器且压缩后的大小(但并未 gzip)。需要补充的是,Angular 2 的尺寸在最终版本有所减小。
为了做一个更真实的对比,我将 Angular 2 官方教程都实现了一遍,结果:
- Angular 2: 764k 压缩后
- React + Redux: 151k 压缩后 可以看到,做一个差不多的东西,Angular 2 目前的尺寸是 React + Redux 的五倍还多。
不过,我承认关于框架大小的担忧可能被夸大了:
大型应用往往至少有几百 KB 的代码,经常还更多,不管它们是不是使用了框架。开发者需要做很多的抽象来构建一个复杂的软件。无论这些抽象是来自框架的还是自己手写的,它都会对应用的加载性能造成负面影响。
就算你完全杜绝框架的使用,许多应用仍然是几百 KB 的 JavaScript 在那。 — Tom Dale JavaScript Frameworks and Mobile Performance
Tom 的观点是对的。像 Angular、Ember 这样的框架之所以更大是因为它们自带了更多的功能。
但是,我关心的点在于:很多应用其实用不到这种大型框架提供的所有功能。在这个越来越拥抱微服务、微应用、单一职责模块(single-responsibility packages)的时代,React 通过让你自己挑选必要模块,让你的应用大小真正做到量身定做。在这个有着 200,000 个 npm 模块的世界里,这点非常强大。
- React 信奉Unix 哲学
React 是一个类库。它的哲学与 Angular、Ember 这些大而全的框架恰恰相反。你可以根据场景挑选各种时髦的类库,搭配出你的最佳组合。JavaScript 世界在飞速发展,React 允许你不断用更好的类库去迭代你应用中的每个小部分,而不是傻等着你选择的框架自己升级。
Unix 久经沙场屹立不倒,原因就是:
小而美、可组合、目的单一,这种哲学永远不会过时。
React 作为一个专注、可组合并且目的单一的工具,已经被全世界的各大网站们使用,预示着它的前途光明(当然,Angular 也被用于许多大牌网站)。
- 谢幕之战
Angular 2 相比第一代有着长足的进步。新的组件模型比第一代的指令(directives)容易掌握许多;新增了对于同构/服务器端渲染的支持;使用虚拟 DOM 提供了 3-10 倍的性能提升。这些改进使得 Angular 2 与 React 旗鼓相当。不可否认,它功能齐全、观点鲜明,能够显著减少 “JavaScript 疲劳” 。
不过,Angular 2 的大小和语法都让我望而却步。Angular 致力的 HTML 中心设计比 React 的 JavaScript 中心模型要复杂太多。在 React 中,你并不需要学习 ng-什么什么 这种框架特有的 HTML 补丁(shim),你只要写 JavaScript 就好了。
接下来我将要用 TypeScript 来写 Angular2 , 也可以用 JavaScript 或者 Dart . 但是,API参考手册以及附件文档章节在 JavaScript 语种下不可用,官方建议TypeScript 版本 .
- 2.1. selector - 声明选择符
- 2.2. template/templateUrl - 声明模板
- 2.3. styles/styleUrls - 设置样式
- 2.4. properties - 声明属性
- 2.5. events - 声明事件
- 2.6. directives - 引用指令
- 6.1. NgForm - 表单指令
- 6.2. NgControlName - 命名控件指令
- 6.3. NgControlGroup -命名控件组
- 6.4. NgFormControl - 绑定已有控件对象
- 6.5. NgFormModel - 绑定已有控件组