8分钟为你详解React、Angular、Vue三大前端技术
引言
本文作者对于当下顶级的前端开发技术做个相对详尽的探究,目的是为了解开这些前端技术的面纱,看看各自的庐山真面目。希望本文对现有或者以后的业务开发有指导或者借鉴作用。
React
React(也被称为React.js或ReactJS)是一个用于构建用户界面的JavaScript库。它由Facebook和一个由个人开发者和公司组成的社区来维护。
基本用法
下面是一个简单的React在HTML中使用JSX和JavaScript的例子。
<div id="myReactApp"></div>
<script type="text/babel">
function Greeter(props) {
return <h1>{props.greeting}</h1>;
}
var App = <Greeter greeting="Hello World!" />;
ReactDOM.render(App, document.getElementById("myReactApp"));
</script>
Greeter函数是一个React组件,它接受一个属性问候语。变量App是Greeter组件的一个实例,其中问候语属性被设置为 "Hello World!"。然后,ReactDOM.render方法将我们的Greeter组件渲染在DOM元素(id为 myReactApp)中。
在web浏览器中显示时,结果将是:
<div id="myReactApp">
<h1>Hello World!</h1>
</div>
显著特点
组件化
React代码由称为组件的实体组成。组件可以使用React DOM库渲染到DOM中的一个特定元素。当渲染一个组件时,可以传入被称为 "props "的值。
ReactDOM.render(<Greeter greeting="Hello World!" />, document.getElementById('myReactApp'));
React中声明组件的两种主要方式是通过功能函数组件和基于类的组件。
功能函数组件
功能组件是用一个函数声明,用来返回一些JSX。
const Greeting = (props) => <div>Hello, {props.name}!</div>;
类组件
基于类的组件是使用ES6类来声明的。它们也被称为 "有状态 "组件,因为它们的状态可以在整个组件中保持,并且可以通过props传递给子组件。
class ParentComponent extends React.Component {
state = { color: 'green' };
render() {
return (
<ChildComponent color={this.state.color} />
);
}
}
虚拟 DOM
另一个值得注意的特点是React使用了虚拟文档对象模型,也就是虚拟DOM。React创建了一个内存中的数据结构缓存,计算得出变化差异,只渲染实际变化的子组件, 从而高效地更新浏览器显示的DOM。
生命周期方法
JSX
JSX,即JavaScript XML,是对JavaScript语言语法的扩展。JSX在外观上类似于HTML,它提供了一种开发者熟悉的语法结构化组件渲染的方法。React组件通常是使用JSX编写的,尽管不一定非要使用JSX(组件也可以用纯JavaScript编写)。JSX类似于Facebook为PHP创建的另一种名为XHP的扩展语法。
class App extends React.Component {
render() {
return (
<div>
<p>Header</p>
<p>Content</p>
<p>Footer</p>
</div>
);
}
}
嵌套元素
属性
JavaScript表达式
<h1>{10+1}</h1>
<h1>11</h1>
条件语句
class App extends React.Component {
render() {
const i = 1;
return (
<div>
<h1>{ i === 1 ? 'true' : 'false' }</h1>
</div>
);
}
}
<div>
<h1>true</h1>
</div>
class App extends React.Component {
render() {
const sections = [1, 2, 3];
return (
<div>
{sections.length > 0 && sections.map(n => (
/* 'key'必须唯一 */
<div key={"section-" + n}>Section {n}</div>
))}
</div>
);
}
}
<div>
<div>Section 1</div>
<div>Section 2</div>
<div>Section 3</div>
</div>
用JSX编写的代码需要被Babel等工具进行转换以后才能被Web浏览器所理解,这种处理一般是在软件构建过程中进行的,然后再部署构建后的应用程序。
超越HTML的架构
React的基本架构不仅仅适用于在浏览器中渲染HTML。例如,Facebook有动态图表,可以渲染到<canvas>标签,而Netflix和PayPal使用通用加载,在服务器和客户端上渲染相同的HTML。
React Hooks
Hooks是让开发者从函数组件中 "钩入"React状态和生命周期特性的函数。它们使代码具有更强的可读性且更易理解。Hooks并不在类组件内工作,它的终极目标是在React中消除类组件的存在。
React提供了一些内置的Hooks,如useState、useContext、useReducer和useEffect等。它们都在Hooks API参考书中做了说明。使用最多的是useState和useEffect,分别在React组件中控制状态和检测状态变化。
Hooks规则
Hooks也有一些规则,在使用Hooks之前必须遵循这些规则:
l 钩子只能在顶层调用(不能在循环或if语句中调用)。
l 钩子只能在React函数组件中调用,不能在普通函数或类组件中调用。
定制Hooks
构建自己的Hooks,也就是所谓的自定义Hooks,可以让你把组件逻辑提取到可重用的函数中。自定义钩子是一个名称以 "use "开头的JavaScript函数,它可以调用其他的钩子。钩子的规则也适用于它们。
常用术语
Flux架构的使用
为了支持React的单向数据流的概念(与AngularJS/Angular的双向数据流形成对比),Flux架构是流行的模型-视图-控制器(MVC)架构的具有代表性的替代方案。Flux的特点是,数据动作通过中央调度器发送到一个存储仓库,而对存储仓库数据的变化会被传送回视图。当与React一起使用时,这种传送是通过组件属性完成的。
Flux可以被认为是观察者模式的一个变种。Flux架构下的React组件不应该直接修改传递给它的任何props,而是应该传递回调函数,这些回调函数可以创建由调度器发送的数据动作来修改存储仓库。数据动作是一个对象,其职责是描述已经发生的事情:例如,一个数据动作描述的是一个用户 "follow"另一个用户。它可能包含如下数据:
历史
常用命令
创建工程:
npx create-react-app my-app
开发环境运行:
npm start
生产环境打包:
npm run build
官方网站
http://reactjs.org/
最新版本
16.13.1于2020年3月19日
授权
MIT License
Angular
Angular(通常被称为 "Angular 2+"或 "Angular v2及以上版本")是一个基于TypeScript的开源Web应用框架,由Google的Angular团队和由个人以及企业组成的社区领导。Angular是由构建AngularJS的同一个团队从零开始重写的。
Angular和AngularJS的区别
1.Angular没有 "Scope"或控制器的概念,相反,它使用组件的层次结构作为其主要的架构特征。
2.Angular有不同的表达式语法,重点是"[]"用于属性绑定,"() "用于事件绑定
3.模块化 - 许多核心功能已转移到模块上
4.Angular推荐使用微软的TypeScript语言,它引入了以下特性:
静态键入,包括Generics
注解
5.TypeScript是ECMAScript 6 (ES6)的超集,向后兼容ECMAScript 5(即:JavaScript)。
6.动态加载
7.异步模板编译
8.由RxJS提供的迭代回调。RxJS限制了状态的可见性和调试,但这些问题可以通过像ngReact或ngrx这样的反应式附加组件来解决。
9.支持Angular Universal,可以在服务器上运行Angular应用程序。
历史
命名
版本2
版本4
版本5
版本6
版本7
版本8
版本9
更小的软件包
更快的测试
更好的调试
改进的CSS类和样式绑定
改进的类型检查
改善了构建错误
改善了构建时间,默认开启AOT功能
提高国际化功能
特点
组件化
<h2>Products</h2>
<div *ngFor="let product of products">
<h3>
{{ product.name }}
</h3>
</div>
Typescript部分
export class ProductListComponent {
products = products;
}
路由
@NgModule({
imports: [
BrowserModule,
ReactiveFormsModule,
RouterModule.forRoot([
{ path: '', component: ProductListComponent },
{ path: 'products/:productId', component: ProductDetailsComponent },
])
],
数据管理
定义服务类
export class CartService {
items = [];
constructor(
private http: HttpClient
) {}
addToCart(product) {
this.items.push(product);
}
getItems() {
return this.items;
}
clearCart() {
this.items = [];
return this.items;
}
getShippingPrices() {
return this.http.get('/assets/shipping.json');
}
}
调用服务类
export class ShippingComponent implements OnInit {
shippingCosts;
constructor(
private cartService: CartService
) {
}
ngOnInit() {
this.shippingCosts = this.cartService.getShippingPrices();
}
}
常用命令
从终端上,全局安装Angular CLI:
使用 ng new 命令创建一个新的 Angular CLI 工作区:
开发环境运行:
生产环境打包:
官方网站
最新版本
授权
Vue
概述
历史
特点
组件化
<div id="tuto">
<button-clicked v-bind:initial-count="0"></button-clicked>
</div>
<script>
Vue.component('button-clicked', {
props: [ "initialCount" ],
data: () => ({
count: 0,
}),
template: `<button v-on:click="onClick">Clicked {{ count }} times</button>`,
computed: {
countTimesTwo() {
return this.count * 2;
}
},
watch: {
count(newValue, oldValue) {
console.log(`The value of count is changed from ${oldValue} to ${newValue}.`);
}
},
methods: {
onClick() {
this.count += 1;
}
},
mounted() {
this.count = this.initialCount;
}
});
new Vue({
el: '#tuto',
});
</script>
模板
反应式系统
变换效果
路由
单页面应用程序(SPA)的一个传统缺点是无法分享到特定网页中的确切 "子 "页面的链接。由于SPA只向用户提供一个基于URL的服务器响应(它通常服务于index.html或index.vue),因此通常情况下,将某些屏幕作为书签或分享到特定部分的链接是很困难的,甚至是不可能的。为了解决这个问题,许多客户端路由器用 "hashbang"(#!)来划分动态URL,例如page.com/#!/。然而,在HTML5中,大多数现代浏览器都支持不使用hashbang的路由。
Vue提供了一个界面,可以根据当前的URL路径来改变页面上显示的内容 – 可以有多种方式(无论是通过电子邮件链接、刷新还是页面内链接)。此外,当某些浏览器事件(如点击)发生在按钮或链接上时,使用前端路由器可以有意识地转换浏览器路径。Vue本身并没有自带前端路由。但开源的 "vue-router "包提供了一个API来更新应用程序的URL,支持返回按钮(导航历史记录),并支持电子邮件密码重置或电子邮件验证链接的认证URL参数。它支持将嵌套路由映射到嵌套组件,并提供精细化的过渡控制。添加了vue-router后,组件只需映射到它们所属的路由,父/根路由必须指明子路由的渲染位置。
<div id="app">
<router-view></router-view>
</div>
...
<script>
...
const User = {
template: '<div>User {{ $route.params.id }}</div>'
}
const router = new VueRouter({
routes: [
{ path: '/user/:id', component: User }
]
})
...
</script>
上面的代码:
1.在websitename.com/user/<id>中设置一个前端路径。
2.这将在(const User...)中定义的User组件中呈现。
3.允许用户组件使用$route对象的params键输入用户的特定ID:$route.params.id。
4.这个模板(根据传递到路由器中的参数变化)将被渲染到DOM的div#app里面的<router-view></router-view>。
5.最后生成的HTML将是:
websitename.com/user/1:
<div id="app">
<div>
<div>User 1</div>
</div>
</div>
生态系统
官方工具
官方程序库
常用命令
安装工具
npm install -g @vue/cli
创建工程:
vue create my-project
开发环境运行:
npm run serve
生产环境打包:
npm run build
官方网站
https://vuejs.org/
最新版本
2.6.1于2019年12月13日
授权
MIT License
小结
本文对于当前顶级的前端技术做了较为详尽的探索,前端技术一个大的方向是单页应用 (SPA,Single Page Application),我们在选取针对本业务的前端技术时需要结合如下几个方面来考虑:
成员当前技能,这是一个很现实的问题,大多数程序员会选择自己比较熟悉的技术。这里要思考一下,目前自己熟悉的技术是不是最优选项?
可利用的学习时间,如果发现要使用的技术需要一些时间学习,这个时间的开销到底会不会与开发进度有冲突?
能否保证项目的复杂度最低,这个是比较关键的因素。先进技术之所以先进就是因为可以让开发者把时间和精力放在真正的业务开发上面来,如果要使用的技术需要进行很多与业务不相关的配置,就需要问一个问题,有没有更好的办法?
你使用过这三种前端技术吗?或者有更喜欢的语言?欢迎前来社区,跟我们分享一下你在前端设计中的心得体会,结实更多志同道合的伙伴。
↓点击阅读原文,进入华为云社区