⤴Top⤴

Angular、React 和 Vue

博客分类: 前端

Angular、React 和 Vue

Angular、React 和 Vue

都 9102 年了,对于前端三大框架自己都有些接触,一直没有做一下总结,这次趁分享的机会好好理一下。我们接下来会探讨:

  1. Angular、React 和 Vue 是什么,为什么存在?
  2. 他们分别有什么特性?
  3. AngularJS 和 Angular 有什么区别吗?Vue 是“抄袭” AngularJS 吗?
  4. 他们在未来的发展趋势是什么
  5. 我应该选择哪一个
  6. 我学不动了怎么办

当然在介绍三大框架之前,我们先粗略看下这方面的前端发展史。

前端发展史

前端的发展一直都很迅速,这一切都可以总结为四个字,即 业务驱动。很好理解,场景和业务的复杂度越来越高,用户的需求也越来越多,用户体验也越来越严苛,因而我们的关注点和技术也时刻在变,如果不能顺应这股潮流,那么只能被淘汰。

1、针对于 PC

在很久很久之前,前端还在被叫做切图仔的时代,如何把图切得又精致又好看是门技术活儿,当然开玩笑,那时候前端还是主要负责做一个页面模板,然后拿给后端渲染。自从 ajax 横空出世,开创 web2.0 时代,开发模式也逐渐趋近于前后端分离,但是这个阶段主要还是根据 W3C 制定的标准来解决浏览器兼容性问题,因此 jQuery 应运而生,加上 api 简单易用,因此很大程度上流行了起来。但是它的缺点是什么呢,它的关注点一直在 DOM 而不是数据,而操作 DOM 一直是个繁琐的过程,而且对性能有很大影响。所以随着技术的演进,我们需要面向对象的编程思想,我们要能够提供一系列解决方案,因此前端的开发模式也逐渐演变至 MVVM,我们只需要关注数据,让框架自动去更新 DOM 状态就行了。在这种模式下,三足鼎立的局面就此呈现:

  1. 2009 - AnguarJS
  2. 2013 - React
  3. 2014 - Vue
  4. 2016 - Angular

angular-react-vue-jquery.jpeg

而关于 MVVM 的解释,这里引用此篇博客的图:

MVVM

2、 针对于 移动端

随着智能手机的普遍,移动端的需求也越来越多,因此更多关注响应式设计和用户体验。hybrid 应用也逐渐火热,但是它在体验和性能上,仍然比原生要差很远。所以之后阿里推出了 weex、facebook 推出了 React Native、Google 也推出了 flutter。而在网页开发技术上,Google 更是推出了 PWA,利用 Service workder 等技术来实现离线访问和消息推送等,具体可参考我的这篇博客 👈

在未来的发展道路上,前端还有很多路要走,谁又能知道随着 VR、AR 等的普及,又有哪些框架能够站出来,或者哪些又要退出历史舞台。

他们分别有什么特性

AngularJS

在讲 Angular 之前,必须要提到它的前身 AngularJS,作为老大哥,他 2009 年就出道了,它的背后就是 Google 大佬,因此它的出世必定受到世人的瞩目,那么它的出现给我们带来了什么 pros and cons:

Angular 特指 2.x 以上版本,1.x 版本成为 AngularJS

让我们来看看一个标准的 AngularJS 的示例,ng-app 的启动过程可以参考我的这篇博客:

<html ng-app>
  <head>
    <script src="http://code.angularjs.org/angular-xxx.min.js"></script>
  </head>
  <body>
    <div>
      <label>Name:</label>
      <my-directive />
      <input type="text" ng-model="name" placeholder="Enter your name">
      <hr>
      <h1>Hello, { {  name || 'World' } }!</h1>
    </div>
  </body>
</html>

成也萧何,败也萧何。正是双向数据绑定的脏检测机制太消耗性能,对于中大型应用的话,每一次检测都是致命的,再加上 AngularJS 本身太臃肿,又对移动端的支持不是那么完善,因此它的替代者 Angular 出现了。

Angular

虽然 Angular 在模式上一定程度上继承了 AngularJS,比如指令、双向绑定等,也有一些做了优化换了名字,比如 filter 改为 pipe 管道等,但是很多地方它的实现方式更加优化了,同时最大的改动是,它完全由 TypeScript 编写。因此从这个角度来看,Angular 完全是区别于 AngularJS 单独存在的,那它总共带来了哪些变化呢:

import { Component, ViewEncapsulation } from '@angular/core';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.less'],
  encapsulation: ViewEncapsulation.Emulated,
})

export class AppComponent {
  title = 'angular-demo';
}

对于双向数据绑定,Angular 通过 Zone 优化了脏检测的方式,采用猴子补丁(Monkey-patched)运行时动态替换的方式,将 JavaScript 中的异步任务都进行了包装,这使得这些异步任务都能运行在 Zone 的执行上下文中,每个异步任务在 Zone 中都是一个任务。从而实现了监听,然后去执行变化检测。对于 Angular,任何数据都是从顶部往底部流动,即单向数据流,而且我们可以通过 onPush 策略来控制哪些部分可以跳过检测,从而避免不必要的性能损耗。我们可以简单的看一下变化检测器的状态:

export declare enum ChangeDetectorStatus {
  CheckOnce = 0, // 表示在执行 detectChanges 之后,变化检测器的状态将会变成 Checked
  Checked = 1, // 表示变化检测将被跳过,直到变化检测器的状态恢复成 CheckOnce
  CheckAlways = 2, // 表示在执行 detectChanges 之后,变化检测器的状态始终为 CheckAlways
  Detached = 3, // 表示该变化检测器树已从根变化检测器树中移除,变化检测将会被跳过
  Errored = 4, // 表示在执行变化检测时出现异常
  Destroyed = 5 // 表示变化检测器已被销毁
}

同样,更多细节请参考我的这篇博客 👈

React

React 是 facebook 于 2013 年推出的库,严格意义上并不是框架,它又带来了什么呢:

React 作为一个库,优点就是灵活,但如果要开发项目时,就得入手 React 全家桶,虽然基本都是无缝式接入,但是还是要考虑其他依赖库的稳定性:

function HelloMessage {
  return (
    <div>
      Hello {this.props.name}
    </div>
  )
}

ReactDOM.render(
  <HelloMessage name="World" />,
  document.getElementById('hello-example')
)

React 介绍可以参考我的这篇博客 👈

Vue

Vue 作为最后一个上场的,自然吸收了天地之精华,去粗取精,那么尤大又为它带来了什么呢:

额,这么一看,Vue 的确是在 AngularJS 和 React 身上取了不少经,但它自身也做了不少优化,比如指令简化了很多,双向数据绑定也是基于 Object.defineProperty 来实现,可以参考 Vue 深入响应式原理。同时它也带来了新的一些特性,比如 computed 计算属性等:

<template>
  <div id="app">
    <img alt="Vue logo" src="./assets/logo.png">
    <HelloWorld msg="Welcome to Your Vue.js App"/>
  </div>
</template>

<script>
import HelloWorld from './components/HelloWorld.vue'

export default {
  name: 'app',
  components: {
    HelloWorld
  }
}
</script>

而 Vue3.0 也呼之欲出,我们可以提前看下它做出的一些变化,更多可以参考这篇文章:

这个 api 写起来你会发现跟 React Hooks 极其相似,但是按照尤大的解释,性能上会好一些,而且写起来更简单:

# React Hooks
function App() {
  const [count, setCount] = useState(0);
  return (
    <div className="App">
      <button onClick={() => setCount(count - 1)}>add</button>
      <h2>{count}</h2>
      <button onClick={() => setCount(count + 1)}>remove</button>
    </div>
  );
}

# Vue Function-based
const App={
  template: `
    <div class="App">
      <button @click="addCount">add</button>
      <h2>8</h2>
      <button @click="removeCount">remove</button>
    </div>
  `,
  setup() {
    const count = value(0);
    const addCount = () => count.value++;
    const removeCount = () => count.value--;
    return {
      count,
      addCount,
      removeCount,
    }
  }
}

总结评价 Vue 的话,我觉得应该是”前启 Angular,后继 React”,毕竟它的确充分吸收了 Angular 和 React 这两位前辈的优点和长处,并更好的运用于自身。👍

Vue 介绍可以参考我的这篇博客 👈

他们在未来的发展趋势是什么

市场占有率及性能

三大框架目前市场趋势可以参考下面:

谷歌趋势:

angular-react-vue-google-trends.png

百度趋势:

angular-react-vue-baidu-trends.png

npm 趋势:

angular-react-vue-npm-trends.png

我们可以看到 Angular 和 React 在国际上使用还是很多的,而且发展趋于稳定,社区也比较强大。而 Vue 的话近几年发展速度很快,在国内已经达到很高的占有率,相比之下它的发展目前并不稳定。我们可以再看一看他们之间的性能测试比较:

angular-react-vue-benchmark.png

单向 or 双向数据绑定

数据绑定来说,单向和双向都有适合自己的场景,虽然双向绑定带来了很多便利,但仍有很多不容忽视的问题:

状态管理

通过状态管理容器可以更方便管理数据和追踪变更,更容易维护和侦错。那是不是这样就完了,还有一个书写的问题,既然要有效管理这些数据,样板代码自然就多了,比如原生 redux 就一直被诟病,因此我们可以借助类似 redux-sauce 或者 iron-redux 来简化书写:

Angular React Vue
ngrx/store Mobx / Redux Vuex

SSR

服务端渲染,相较于客户端渲染的两个比较大的优势:

Angular React Vue
Angular Universal Next Nuxt

支持原生开发

Angular React Vue
Ionic / NativeScript React-Native Weex / NativeScript

CSS In JS or CSS Modules

CSS 模块化的解决方案有很多,主要是针对全局作用域问题,现主要有两类,具体参考我的这篇博客:

TypeScript

JS 的松散语法给我们带来便利的同时,也带来了一些隐患:一些(通常是低级的)错误,要等到运行时才会抛出来。而 TypeScript 增加了静态类型检查,加强了数据的可预测性,大大降低了 TypeError 的几率。代码的维护和重构也更加方便。具体细节可以参考我的这篇博客 👈

Rollbar(类似 Sentry 可实时捕捉错误并汇集日志的平台) 于 2018 年总结的 top10 JavaScript Errors,大部分都可以杜绝

我应该选择哪一个

现代框架之间的差距日渐减少,在选型方面不用太过纠结,实在要说的话可以参考下:

我学不动了怎么办

撸起袖子干

参考链接

  1. 前端发展历程 By 411020382
  2. web2.0 時代 By 前端探索旺
  3. 前端三大框架数据流动和原理 By recallhyx
  4. React vs Angular vs Vue.js — What to choose in 2019? By TechMagic
  5. 2019 年,Flutter 和 React Native 谁主沉浮 By 前端小智
  6. 给 2019 前端的 5 个建议 By camsong