【原译】React vs Angular 2: 战争继续
原文地址:https://tech.evojam.com/2016/03/31/react-vs-angular2-the-fight-rages-on/ ??google的Angular和Facebook的React是现在最流行(但不是只有两个)的浏览器端应用开发工具,它们都是很优秀的解决方案。然而angular 2仍然在beta版中,Google的一部分工程师已经对它进行测试了。使用react开发的应用也很多,像instagram,netlfix,paypal等。 ?残忍的战争就要到来了。 第一滴血已经有一篇”血腥“的文章《Angular 2 versus React》(作者:Cory House)来比较angular2与react,它体现了两者很多方面的亮点,第一次对决已经结束,但是大战才刚刚开始。(译者注:老外写个文章真的一定要这么夸张吗?哈哈~) 认清你的对手
Cory House告诉我们:
我想补充的是react有很多优秀的浏览器开发插件,然而并没有看到angular 2的。 竞技场??为了比较这些前端的技术,我做了一些TODO应用。为了使问题更加简单,我在两个应用中只使用了Redux core(受angular 2-introduction to Redux启发)。两个都是使用typescript开发的,所以比较起来比较清晰些。你可以对比下代码: – Redux Core: https://github.com/evojam/redux-todo-lib – Angular2 App: https://github.com/evojam/angular2-redux-sample-app – React App: https://github.com/evojam/react-redux-sample-app 对抗??两者的核心都是一个component或是一个view单元。两个都将你的app形成一个组件树。它们都鼓励将数据通过顶层传递给组件树。根到叶子的数据流思路使我们开发的应用"更灵活",所以现在开始。 第一轮:功能组件??在这个树形结构的基础应用中,每个顶层树是一个组件,每个组件的特点:
??在angular2和React中,输入都是通过子节点属性(不是html属性)从一个元素传递到它的子树,两种解决方案中,视图view都可以理解为xml树。 TodoList组件??一个可复用、可选择、简单的todo list需要做到两点--todos数组(我做的数组)和过滤的方式(要展示的数组)。所以我们的组件输入可以是这样的: interface ITodoListProps { todos: ITodo[]; filter: FilterType; } ??而组件在任何地方都可以这样使用: -- React <TodoList todoList={todos} filter={filterType}/> --Angular 2 <ul [todoList]="todos" [filter]="filterType"></ul> 下面是React组件的定义: // src/components/todo-list.tsx import { Todo } from './todo'; export function TodoList(props: ITodoListProps): JSX.Element { return ( <ul className="todo-list"> {todosFilter(props.todoList,props.filter) .map(todo => ( <Todo todo={todo} key={todo.id}/> ))} </ul> ); } 下面是Angulart2组件定义的版本: // src/components/todo-list.ts import { Todo } from './todo'; @Component({ changeDetection: ChangeDetectionStrategy.OnPush,directives: [Todo],host: {'class':'todo-list'},pipes: [TodosFilter],selector: '[todoList]',templateUrl: '/src/components/todo-list.html' }) export class TodoList implements ITodoListProps { @Input() todoList: ITodo[]; @Input() filter: FilterType; } // src/components/todo-list.html <template ngFor #todo [ngForOf]="todoList | todosFilter:filter"> <li [todo]="todo"></li> </template> ??毫无疑问,React版本是没有状态,更纯正,更简单,它使用data并返回dom,很好。 ??这里可以运行但是不能正确编译,我不知道它是不是typescript支持性的原因或者React编码输入的错误(如果知道错误请给issue)。无论怎样,它失败了,我不得不在React组件基础上切换成一个class。React保存了状态--就是组件成员的属性--但是属性仍然可以被当做immutable的数据输入: // src/components/todo-list.tsx import { Todo } from './todo'; export class TodoList extends Component<ITodoListProps,{}> { render(): JSX.Element { return ( <ul className="todo-list"> {todosFilter(this.props.todoList,this.props.filter) .map(todo => <Todo todo={todo} key={todo.id} />)} </ul> ); } } ??angular2 版本需要多得多的配置,对于这个简单的应用要干的事情太多了。这是因为angular没有将js和html混合在一起(directives,host,pipes,selector,templateUrl)和更多复杂的数据修改检测机制(数据监听)。
??React的组件功能(或是渲染方法)返回整个顶层模板包含的组件树。 return ( <ul className="todo-list"> { todoList.map( todo => <Todo todo={todo}/> ) } </ul> ); ??在angular中,组件是与组件的根元素绑定的(通过上面提到的选择器selector),这个组件的根元素就被称为host,所以在angular模板中,我们只放入根元素的内容: // src/components/todo-list.html <li [todo]="todo" *ngFor="#todo of todoList"></li> ??如果我们想添加一下东西(例如css的class,属性值)给host元素,我们称之为host定义,例如 Todo 组件??所以我们现在开始绑定一些事件处理器。angular todo组件就像这样: // src/components/todo.ts interface ITodoProps { todo: ITodo; } @Component({ host: {'class': 'todo'},selector: '[todo]',templateUrl: '/src/components/todo.html' }) export class Todo implements ITodoProps { constructor(private todoActions: TodoActions) {} @Input() todo: ITodo; @HostBinding('class.done') private get isCompleted() { return this.todo.completed; } } // src/components/todo.html <button (click)="todoActions.toggleTodo(todo.id)" class="toggle"> {{ todo.text }} </button> <button (click)="todoActions.removeTodo(todo.id)" class="remove ion"> Remove </button> ??我们把 ??而React版本: interface ITodoProps { todo: ITodo; key: string; } export class Todo extends Component<ITodoProps,{}> { private getToggleAction(todo: ITodo) { return () => { todoActions.toggleTodo(todo.id); } } private removeTodo(todo: ITodo) { todoActions.removeTodo(this.props.todo.id); } public render(): JSX.Element { return ( <li className={'todo' + (this.props.todo.completed ? ' done' : '')}> <button onClick={this.getToggleAction(this.props.todo)} className="toggle"> {this.props.todo.text} </button> <button onClick={this.removeTodo.bind(this)} className="remove ion"> Remove </button> </li> ); } } ??我们把
??我也不喜欢 组合:ReactTodo <li className={…}> <button onClick={…} className="toggle">{…}</button> <button onClick={…} className="remove ion">Remove</button> </li> TodoList <ul className="todo-list"> { todoList.map( todo => <Todo todo={todo}/> ) } </ul> 对于对象更深的结构: <TodoList todoList={this.props.todoList.todos} filter={this.props.filter}/> 输出为: <ul class="todo-list" data-reactid=".0.1.1…"> <li class="todo" data-reactid=".0.1.1…"> <button class="toggle" data-reactid=".0.1.1…"> Toggle </button> <button class="remove ion" data-reactid=".0.1.1…"> Remove </button> </li> … </ul> 组合:Angular2Todo @Component({ host: {'class': 'todo'},… }) export class Todo … { … @HostBinding('class.done') private get isCompleted() { … } } <button (click)="…" class="toggle">{{ … }}</button> <button (click)="…" class="remove ion"></button> TodoList @Component({ host: {'class':'todo-list'},… }) export class TodoList … { … } <template ngFor #todo [ngForOf]="todoList | todosFilter:filter"> <li [todo]="todo"></li> </template> 对于对象更深的结构: <ul [todoList]="todoList.todos" [filter]="filter"></ul> 输出为: <ul class="todo-list"><!--template bindings={}--> <li class="todo"> <button class="toggle">asd fasd f</button> <button class="remove ion">Remove</button> </li> … </ul> 第一轮结果??React在开发轻量级单一组件场景下具有绝对优势。如果你的应用可以用数据视图简单描述清楚的话React似乎是最佳的解决方案。而且无疑是我们见过的最灵活的视图渲染框架。但是事件处理逻辑越多,UI渲染越复杂,angular2就越具有优势。事实上,angular2的组件配置和绑定声明复杂度和组件的复杂性成反比。此外,它还有灵活的使用方式(从数据到视图的绑定)。可能某一天Reactangular或者Angulareact框架能让我们高效的在一个应用中使用两种实现方式。但现在我们必须要选择。 ??灵活与否,都应该以减轻开发者的痛苦来作为考量。代码的可读性也是一方面,但目前html在这里是很重要的判断。 第二轮:视图美学??让我们来准备一个新的组件来处理更复杂的结构--列表结构。 angular2 <li *ngFor="#todoList of lists trackBy _byId" [class.active]="isCurrent(todoList)" class="todo-lists-list-item"> <header [todo-list-header]="todoList"></header> <ul *ngIf="!isCurrent(todoList)" class="todo-list"> <li *ngFor="#todo of todoList.todos" class="todo-preview" [class.done]="todo.completed"> {{ todo.text }} </li> </ul> <editable-list *ngIf="isCurrent(todoList)" [todoList]="todoList"> </editable-list> </li> React <ul className="todo-lists-list"> {this.props.lists.map(list => ( <li key={list.id} className={this.listClassName(list)}> <TodoListHeader todoList={list}/> {list.id !== this.props.currentId ? ( <ul className="todo-list"> {list.todos.map(todo => ( <li key={todo.id} className={this.todoClassName(todo)}> {todo.text} </li> ))} </ul> ) : ( <EditableList todoList={list} filter={this.props.filter}/> )} </li> ))} </ul> 第二轮结果??有什么好说的吗?选择你喜欢的就好了~ ??ok,我认为 第三轮:数据修改监听??我们在此声明一件重要的事情--Dom修改(在修改被检测到以后)在两种框架中处理方式是类似的。它们只修改确实需要改变的部分。我们来看下如果发生数据变化,处理的方式有什么不同; React ??React的基本处理方式很简单。如果组件的
??当然也可以通过调用 ??你可能会注意到例子里面的 Angular ??angular 团队决定使用稍微不同的方式。他们包含了 ??在样例中,我使用了 ??就像React的 第三轮结论??两种解决方案都提供了一个相对健全的途径,然而React的默认修改检测无疑更优一些。另一方面,angular这种在底层的检测相当于一个浏览器开发玩家使用的因为它把检测插入到浏览器一些异步调用层,所以广播检测的职责对开发者来说不可控。当然每种方案都有他们不尽人意的地方。React的组件检测如果数据不是来自属性的话必须通过手动调用触发,如果使用了其它存储方式会直接触发(Flux 框架)。如果你想让angular变得灵活些,你必须在每个单一的组件定义他们的数据检测触发策略。 ??不过两种方式都很好。angular使用简洁的配置工具实现了更多的扩展性,这点React就没做到。 第四轮:扩展html??做什么?就是像html添加一些功能,让它在更多的元素中被复用。 Angular @Directive({selector: '[inp-alerter]'}) export class InpAlerter { @Input('inp-alerter') inpAlerter: string; @HostBinding() placeholder = 'Write something here'; @HostListener('keyup.enter',['$event.target.value']) onInput(val: string): void { … } } ??上面的例子展示了我们怎样从一个输入属性中获取值、绑定一些其他值给元素属性或给元素添加监听事件。而且它可以用 React ??有一种可能是使用React mixins的方式来实现相同的功能,但是有点过度设计的倾向而且容易出错。无论怎样,开发者必须为应用中使用的每个元素功能创建一个组件。 K.O.??最后一轮决出了胜负,React被战胜了。 ??感谢上帝,这只是个比喻。 ??总之,这是一个angular 1.x统治的世界,而且也正准备走向html扩展元素web components的世界。angular 2赢的了这一轮。但是我确定React不会就此放弃。 落幕??显然,React和Angular 2有很多共同点,他们在处理应用框架和数据上使用了相似的原理。另一方面,每个功能的实现都使用了不同的方式(好吧,组件调用的生命周期还是完全一致的)。这些不同点并不意味着应用开发时的难度,每种方案都提供了足够完善的工具来开发一个大型、严谨、灵活的应用核心。 ??当然React更小并且只涵盖view/component的操作--这是我这里要对比的。缺少向html的扩展机制无疑是React唯一不足的地方。 ??Angular2则更加稳定、可扩展和更加完善。但是它仍然在beta阶段--并且相对对手具有优势因为无论相比angular1还是React的经历来看它具有更加优秀的合并思想。 译文出处:https://ouvens.github.io/article-translation/2016/04/07/react-vs-angular2-fight-rages-on.html 参考文章: Comparison of Angular 2 and React State Management in Angular 2 and React Choosing between React vs. Angular 2 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
- Can't use Subversion command line client: svn
- C# 添加Excel表单控件(Form Controls)
- ruby-on-rails – Rails:我应该如何在控制器之间
- Flex中修改Loading页面
- vue2.0$nextTick监听数据渲染完成之后的回调函数
- Flex手机项目继承IconItemRenderer自定义List组件
- VideoError: 1008: VideoPlayer.iNCManagerClass
- vue2.0 非父子组件之间的单一事件通信
- C#封装的常用文件操作代码类
- [Swift]LeetCode311. 稀疏矩阵相乘 $ Sparse Mat