点击上方“CSDN”,选择“置顶公众号”

关键时刻,第一时间送达!

如果说 2016 是 JavaScript 的疲劳年,那么 2017 年肯定是融合的一年。大多数 JavaScript 框架使用的工具和概念都趋于一致。

在这篇文章中,我将重点介绍 JavaScript 框架之间的一些相似之处,剖析框架之间的设计和思想是如何相互渗透的。

基于组件的架构

组件(components)是一个很棒的概念。设计师喜欢它们,因为通过组件,设计师可以和开发人员拥有共同的语言,能够把系统的设计清楚的表达出来;开发人员喜欢它们,因为这意味着他们可以专注于构建小型,自包含且可重用的特性,然后把它们组合起来构建更大的视图和整个应用程序本身;产品经理喜欢它们,因为可以在多个应用之间共享这些组件。

React 为现代前端开发普及了组件模型的概念。在 Angular 的 1.x 版本时期,社区就有人开始编写基于组件的指令(https://www.airpair.com/angularjs/posts/component-based-angularjs-directives#1-component-based-directives-in-angularjs)。接着在 Angular 1.6 版本中引入了 angular.component(),从而能够更容易的编写基于组件的指令。到了 2016 年,Angular 2.0 带来了真正的组件。同时,Vue 一开始就将组件作为其核心特性之一。

下面是使用这三个框架编写组件的例子,可以看到代码相似度很高:

当然三个框架的代码也存在差异,例如,在 React 中我们可以用函数来实现组件。Angular 和 Vue 可以引用定义在 HTML 文件中的模板。Vue 还可以在一个独立的 `.vue` 文件中编写集 HTML,CSS 和 JS 于一体的组件。然而,组件的核心思想在所有三个框架中都是相同的。

视图的定义

组件的视图(View)部分是当在应用程序的某个地方使用组件时,我们希望框架渲染的内容。在 Angular 中,我们将视图定义为模板,它们是 HTML 的变种,使用类似 mustache/handlebars 的语法来绑定数据——使用两个大括号把 JavaScript 表达式(https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Expressions_and_Operators#Expressions)包裹起来。这些模板同时支持几个内置的组件和指令,允许我们定义模板逻辑,例如条件语句和列表渲染。

React 使用 JSX(https://facebook.github.io/jsx/),可以在 JavaScript 中使用类 XML 的语法定义视图。绑定操作很像模板,JSX 使用一个大括号把 JavaScript 表达式包裹起来。JSX 和模板最大的区别是添加控制语句和模板逻辑的方式。模板依赖于内置的组件和指令,而 JSX 直接使用 JavaScript 语言特性,例如 if 语句,三元操作符或者 `Array.map` 方法等。虽然 JSX 有一定的学习曲线,但你会惊奇的发现其实模板的很多用法和概念是可以迁移到 JSX 中的。

Vue 同时支持上面两种方式。Vue 模板的灵感来源于 Angular,两者的模板逻辑几乎使用相同的组件和指令,数据绑定也都使用两个大括号。通过定义 render 函数(https://vuejs.org/v2/guide/render-function.html#Basics)我们还可以在 Vue 中使用 JSX,而不用使用模板属性。

JSX 的主要好处之一是可以在一个文件中就完成一个组件所有代码的编写,也就是说,这个组件的视图,JavaScript 逻辑甚至样式都可以放在一个文件中。Vue 也支持单文件组件(https://vuejs.org/v2/guide/single-file-components.html)的编写,同时不局限于 JavaScript 代码,你还可以使用 HTML 模板或者 Pug,或者使用 render 函数来实现视图。样式可以使用 CSS,SCSS 或者 PostCSS 等编写。

样式和封装

组件的样式的使用通常有三种不同的风格:

  • 经典:所有的 CSS 都是全局可见的,组件可以使用所有的样式;

  • 封装:每个组件有专属于自己作用域内的局部样式,它不使用任何全局的样式,同时组件内部的样式对外部也不可见;

  • 混合:组件大部分情况下使用自己作用域内的局部样式,但也有一些全局的样式可以级联继承下来。

你是否对其中某种风格更加情有独钟呢?好消息是,三种框架都支持这三种风格。全局 CSS 天然就支持,我们可以在模板中使用 class属性,或者在 JSX 中使用 className 来引用全局的 CSS。

Angular 也内置支持组件作用域内的样式,我们可以从三种封装策略(https://angular.io/api/core/ViewEncapsulation)中选择任何一个,而且样式在加载进组件之前,可以通过 Sass 或者 PostCSS 执行预处理。

Vue 通过单文件组件语法提供对局部样式的支持,直接在 style 标签中添加 scoped 属性即可。和 Angular 类似,我们在 Vue 中也可以配置构建工具实现加载 CSS 之前进行预处理。

CSS Modules(https://github.com/css-modules/css-modules)是另外一种实现模块化和局部 CSS 的流行的做法。在 Vue 中使用 CSS Modules只需要给 `style` 标签添加 `module` 属性即可:

React 没有内置的局部样式支持,然而 React 社区有很多充满活力和创新的解决方案来实现编写组件的局部 CSS。当然我们也可以使用 CSS Modules。

当然,在 React 中实现局部 CSS 更多的情况是使用基于 CSS-in-JS 的函数库,例如 styled-components(https://www.styled-components.com/),glamorous(https://glamorous.rocks/),emotion(https://emotion.sh/)以及其他函数库(https://github.com/MicheleBertoli/css-in-js)。

如果你更倾向于使用 CSS-in-JS 的方案,也有一些函数库支持 Vue,例如 styled-components/vue-styled-components(https://github.com/styled-components/vue-styled-components),emotion-vue styled(https://github.com/emotion-js/emotion/blob/d5d34c0df2be5bae19d21da4e950b03fae03a1b7/README.md#vue-styled)。

组件数据的传递

组件之间是相互隔离的,但组件可以从它的父组件接收数据。在 React 和 Vue 中我们称之为 props,在 Angular 中称之为 inputs。

Props 和 inputs 都是只读的数据,可以在组件的视图中使用,也可以进一步传递给子组件使用,这些数据在组件树中从上往下单向流动。当数据发生更新时,将会触发使用它们的组件进行重新渲染。

子组件必须明确声明它希望接收的 props 或 inputs,我们也可以给这些数据指定类型。在 React 中可以使用 PropsType 函数库(https://www.npmjs.com/package/prop-types)来指定类型,例如:

Vue 也对 props 的校验提供了类似的支持:

Angular 2+ 主要使用 TypeScript 来编写代码,因此,对输入数据的类型校验就交给 TypeScript 了。你只需要使用注解给输入属性指定类型就行。

静态类型检查器功能强大,甚至可以在执行前就能指出代码中存在的问题,从而改善开发流程。对大型应用效果更为显著。因此,在 2017 年初 PropTypes 从 React core 中移除了,现在官方(对大型应用)的建议(https://reactjs.org/docs/static-type-checking.html#flow)是使用 Flow 或者 TypeScript。

TypeScript 对 Vue 的支持并不如 React 和 Angular 那么健壮,但它也在快速改进中。例如微软维护了一个 TypeScript-Starter(https://github.com/Microsoft/TypeScript-Vue-Starter)框架,Vue 官方甚至提供一个函数库(https://vuejs.org/v2/guide/typescript.html#Class-Style-Vue-Components)可以使用 class 风格的语法来编写 Vue 组件。

事件

这三个框架都可以在组件中指定事件处理器,从而实现对 DOM 事件的监听,并在它们被触发时执行某些 JavaScript 代码。

Props 和 Inputs 允许数据在组件树中从上到下流动,但我们通常需要把某些变化从下往上反馈回去。Angular 和 Vue 可以通过发射自定义事件来实现,组件可以绑定到这些自定义事件来实现监听变化。

在 Vue 中可以通过 $emit 来触发自定义事件:

在 Angular 中自定义事件可以通过使用 @Output 修饰符给 EventEmitter 实例添加注解来实现,并通过调用 event emitter 的 emit 方法来触发这个自定义事件:

React 实现自定义事件的方式有点不同,它不是把自定义事件往上抛出,而是让父组件将事件处理器作为 props 传递给子组件,然后等待子组件在合适的时机调用。

总结

本文我重点介绍这三个框架在组件这个概念上的相似点,但事实上框架间在其他很多地方都是相似的。在应用打包,状态管理,响应性和 CLIs 等其他方面,这些框架也在相互学习,最终选用的解决方案也大同小异。将来的某一天也许我们可以共享使用不同框架编写的组件(https://github.com/TheLarkInn/unity-component-specification)。

在过去的几年,前端领域的开发者们都会感觉有些焦虑,因为几乎每隔一个月就会出现一个新的框架需要学习。大家担心时间花费在错误的框架上。现在事情已经发生变化,对其中任何一个框架的投资都将得到回报。你在一个框架中学到的知识几乎都可以迁移到其他框架中。

原文:JavaScript Frameworks: The Year of Convergence

链接:http://blog.rangle.io/javascript-frameworks-the-year-of-convergence/

作者:Varun Vachhar

译者:顾浩鑫

责编:苏宓

JavaScript 框架这一年:React、Angular 们正在互相渗透相关推荐

  1. 几个javascript框架对比(vue,react,Angular等),如何选择?

    javascript框架大对比 React 原生渲染,跨平台开发 规模 向上拓展 向下拓展 Angular 大型应用 TypeScript 体积 学习曲线 Ember 全能框架 Knockout IE ...

  2. JavaScript 年度调查报告:React、Vue 和 Angular 三分天下,谁将在 2018 年独占鳌头?

    点击上方"CSDN",选择"置顶公众号" 关键时刻,第一时间送达! 要论 2017 年最主流的三个 Web 前端框架,应莫过于 Angular.Vue 和 Re ...

  3. 2021 年最佳 JavaScript 框架

    据 Stackoverflow 的 2021 年开发者调查,JavaScript 已连续第八年成为使用最多的语言,有 67.7% 的受访者选择它.之所以如此受欢迎,主要是因为 JavaScript 是 ...

  4. 一文盘点主流JavaScript框架的优缺点

    当今互联网时代,前端开发框架的重要性越来越受到关注.随着JavaScript的不断发展,前端框架也不断涌现.但是,在这么多的框架中,该如何选择适合自己项目的框架呢?本文将会介绍主流的JavaScrip ...

  5. 2021 年最佳 JavaScript 框架排名

    微信搜索逆锋起笔关注后回复编程pdf 领取编程大佬们所推荐的 23 种编程资料! 作者 | Olivia Cuthbert 译者 | Sambodhi 策划 | 刘燕 据 Stackoverflow ...

  6. 【框架】984- 2021 年最佳 JavaScript 框架

    作者 | Olivia Cuthbert 译者 | Sambodhi 策划 | 刘燕 据 Stackoverflow 的 2021 年开发者调查,JavaScript 已连续第八年成为使用最多的语言, ...

  7. 2017年 JavaScript 框架回顾 -- React生态系统

    前一篇文章中,我们介绍了2017年 JavaScript 框架的整体情况.我们也了解到在众多的前端框架中,目前最为庞大又在快速增长的当属 React 了,本文就来重点介绍 React 的生态系统. 首 ...

  8. JavaScript 框架之战结束:React 是最终赢家?

    编译 | 张仕影 出品 | CSDN(ID:CSDNnews) 框架之间的论战一直以来都是 JavaScript 社区的热门话题,也是业内的圣战之一.从刚开始的 jQuery,到后来的 Angular ...

  9. Next.js提供了基于React的简单通用JavaScript框架

    新的通用JavaScript框架Next.js目前已经开源了,它为基于React和服务器的Web应用提供了一个新的可选方案. \\ 来自Zeit的团队在React的基础和组件模型上构建了Next.js ...

最新文章

  1. mysql哪些数据库不能删除吗_为什么我不能删除MySQL数据库?
  2. LVS的DR模式配置
  3. x5675相当于e5_至强X5675比I7 2600强多少 至强X5675相当于几个AMD X2 220
  4. 神策数据林美天于大数据与人工智能分享沙龙分享
  5. Intellij IDEA神器居然还藏着这些实用小技巧,爽!!!
  6. C# EXCEL 透视表使用 多行多列的导出透视表
  7. GsonFormat的使用 (转)
  8. c语言程序设计 k,《C语言程序设计》谭浩强版-教学教案 k.doc
  9. QTP之reporter对象方法全解析
  10. 阿里云导出的镜像raw转换成vmdk格式工具
  11. STM32HAL库微秒延时函数的实现---DWT和SysTick
  12. SQL语句中not in 和not exist的区别
  13. Replacing Elements
  14. 基于UEBA的用户上网异常行为分析
  15. THREE加载模型FBX、OBJ、GLTF
  16. 深入SpringBoot核心注解原理
  17. js-排序-对象key自动排序问题
  18. 【图像处理】像素坐标系、像平面坐标系、相机坐标系、世界坐标系、内参矩阵、外参矩阵
  19. 如何让淘宝店铺排名更靠前 淘宝搜索排名技巧分享
  20. Markdown格式

热门文章

  1. rust笔记10 泛型处理
  2. 南桥芯片组行业调研报告 - 市场现状分析与发展前景预测
  3. 中国可打印标签市场趋势报告、技术动态创新及市场预测
  4. vue2.0的Element UI的表格table列时间戳格式化
  5. asp.net数据库连接php代码,ASP.NET 数据库连接
  6. 张一鸣退一步,换字节跳动的“海阔天空”
  7. iOS 应用启动慢的原因找到了!
  8. 三个锦囊:剖析 5G 安全难题
  9. 荣耀与美团合作推出 “共享笔记本”;传腾讯建议推出美国版微信,已被否;Debian 10.6 稳定版发布|极客头条
  10. 程序员风光背后:从零到BAT数据分析师靠的是什么?