Angular2與React,前端的未來志向何方?
Angular2明年估計就會出來了,對現在滿天的React的衝擊將會如何?未來,前端將走向何方?
去年年底,我回答過一個問題:
2014 年末有哪些比較火的 Web 開發技術? - 徐飛的回答
轉眼間一年過去了,Angular 2發布了beta版,React如日中天,只有Polymer還是不溫不火。
這一年時間內,我也經常觀察前端界的各種趨勢,關注各種創新點,並且跟業內同行進行過一些探討,最終結論是:這三個框架,代表著前端框架目前的三條路線,仍然是並行發展的,只是在發展過程中互相吸收先進的思想。
哪三條路線呢:
- 以Angular,Vue,Aurelia,Avalon為代表的MVVM路線
- React以及相關周邊
- 以Polymer,NovaJS等為代表的Web Components路線
這三條路線本質上都是前端組件化框架/庫,所以,組件化理念是它們的立身之本,雖然大家的實現方式有所不同,但很多理念都是共通的。具體差別在哪裡呢?
在這裡需要先提及三個名詞:
MVVM,Virtual DOM,Web Components
我提這三個詞的意思,並不是說它們就對應於剛才三條路線,人們往往會有誤解:比如認為MVVM是Angular等框架的專利;除了React,別的框架也就不能有Virtual DOM了。
其實不然。
MVVM框架們之所以被冠以MVVM的名號,因為他們都是非常側重於分層的,三層分得一般非常清楚。比如說我們看Vue,它的一個組件中,包含很明顯的三層。
但是在React的實踐中,如果應用的規模增大,數據的組合複雜度高,很可能到最後也搞成了類似VM和M的分層,在這個回答的評論下:如何正確、客觀地評價 React? - 鄧欣欣的回答
@墨磊 提到的:
另,最近一些項目中,在 Flux 或者 類 Flux 的 Store =&> View 這一步,
因為一些歷史原因,依然不得不走向了這樣的過程 ModelStore =&> ViewModelStore =&> View,同樣可以視為 MVVM 吧。
所以,MVVM並非MVVM框架們特有,當基於React或者其他框架的項目變大的時候,仍然有可能作為一種實踐被用起來。
再來看Virtual DOM,目前React是有這個東西的,但MVVM框架的底層一樣可以搞起來。好幾個框架的底層都部分使用了這種理念,比如大家的track by,都可以把數據和DOM之間的關係索引起來,當一個數組的元素交換了,它們可以藉助這些索引關係,不銷毀原有DOM樹,而是直接把數據交換了設置過去。
如果MVVM框架不是使用先生成DOM,再提取模板配置這種方式,而是直接解析模板生成AST,做這層更加容易,而且可以比較容易替換成其他渲染方式,比如在服務端,或者在移動端的Native代碼中渲染。
再看Web Components,主流的MVVM框架其實都在往這個方向靠攏,而React由於使用工程手段解決了Shadow DOM和Scoped CSS這樣的問題,所以對此並不太在意,而且由於它實現的特殊性,要兼容Web Components反而比較難。
D2的時候我曾經跟 @賀師俊在這些方面有過交流,他認為MVVM框架們很可能最終跟Polymer合流,整個前端框架領域被React和MVVM流派平分,鹿死誰手尚未可知。
我覺得,目前的應用場景是足夠大的,每個流派都是可以活得下去的,無所謂東風壓倒西風還是反過來,雙方都能生存下去。到最後,當形成整體解決方案的時候,很可能兩派方案都是殊途同歸:
- 視圖層實現了Virtual DOM
- 宏觀上組件化,形成組件樹
- 微觀上MVVM,並且都應用類似Flux,Redux之類的數據層方案
- 編程模型吸收Immutable和Rx的
- 通信層應用Relay或者Meteor之類的方案
比較大的區別可能是對Web Components標準的應用程度,MVVM系可能都會使用它,並且相應地採用不同的CSS資源管理和構建方案。
去年年底的時候,有一件事情我沒有想到,那就是ES6的普及速度,有鑒於此,我認為,未來一兩年內,ES新版本會成為各路組件化開發方案的默認配置,並且得到廣大開發人員的接受,TypeScript也可能會隨之大放異彩。
另外有一點我沒有考慮到的就是HTTP2,這個經過 @賀師俊指出之後,我覺得很有道理。我總結一下他的觀點:之前我們都會考慮代碼的合併打包等方案,但是當HTTP2普及之後,這方面很可能不是問題,人們會回歸一種只專註於代碼本身,而不是著重考慮現有這些類型的優化方式,所以這可能會對各類工程管控優化方案有個顛覆。
目前能看到的大致這些,一年後來看看。
順便回答你的問題,1-2年內,Angular 2應該不太會顛覆得動React,甚至要超越自身的1.x版本都比較困難,更詳細的見這裡:如何評價 Angular 2 發布 Beta 版本? - 徐飛的回答
倒是Vue,在2016年的增長會很令人期待。干過幾年的前端,並且會在前端這條不歸路上繼續走下去。。。
從開始的ie6風行天下的時刻加入前端這個行業。眼睜睜看著這個行業的風起雲湧,最落寞不過是一個個項目由風光無限轉到寂寥到無人問津。
ie6-8+ firefox 3的時代,jquery+jquery 插件大行其道。那時候面試的時候問的最多一句,jquery的插件有幾種寫法,面向對象的插件與普通插件的異同。jquery的源碼有沒有讀過。你有沒有讀過jquery源碼?dom操作,api精簡,鏈,deferred,這些思想沉澱的深刻。到大而全的框架開發,比如dojo,extjs,jquery UI,YUI是的,這些動輒幾十兆的開發包,掌握一個框架就可以吃一行飯。至今還記得半夜讀extjs的源碼時的一聲聲嘆息,原來js,前端代碼可以這麼寫。
到後來模塊化崛起,問的做多的是,seajs,requirejs,amd,cmd,umd,nginx的combo 的各種差異,而這些也是如數家珍一樣。
html5,webkit,跨終端,css3,sass,less 崛起,bootstrap風靡中國。
nodejs攜著npm攪起前後端分離,js服務端開發拉開序幕。
小而美,函數式,mirojs集錦,undersocre,q等等...一個個前仆後繼的在js中誕生。技術變得日新月異。
再後來ES5,ES6,ES7相繼出台,一方面彌補js在語法上的不足,一方面又像改革的春風吹向前端這個圈子。angular2,reactjs,native,web components。。。web工程化。gulp,grunt,fis。太多太多了。其實這些年走來,看著這些技術有苦澀也有欣慰。這個行業的發展要比以往刀耕火種,沒日沒夜的切圖,圍著設計稿打轉,寫完html,css,寫jquery 動效,至少加了新鮮的熱辣的元素。
我也曾迷茫過,也曾彷徨過,也曾想著換個坑,換個職業,換個人生,看不一樣的風景,聽不一樣的故事。但最後還是留下來了。
做技術就是做人做事。迷茫的時候不如去看看這些人是怎麼想到這些技術,怎麼做出這些成就。看看源碼,看看設計。也就明白了很多道理。angularjs 做個內部管理系統,是足夠的,也是健全的。比extjs好些。你用了,你就知道了,你不用,永遠在門裡面看門外的風景,其實也就只有一個門框的視野。機會只給勇於弄髒自己雙手的年輕人。祝永遠年輕,永遠熱淚盈眶。其實不妨找一下兩者的共同點,就大概能對「未來」有一個大概理解。
首先是component的概念在兩者中都有了實際的抽象,angular 2的@Component和React的createClass,大致的概念和抽象層次是一致的,只不過實現細節有很多不同罷了;這些框架做的,就像jQuery對DOM API做的那樣,在Web Component實現沒有最終一致成型之前,給開發者市場提供一種解決了兼容性的方案。Component的狀態是自維護的,架構複雜應用的思路會清晰不少。
其次是Declarative,declarative的語言設計好了,原型方便,介面直觀,復用定製間有比較好的平衡,容錯處理好等等,對設計人員和開發人員都是福利。你不需要寫比較複雜的JS來實現功能了,只需要寫HTML就可以。
這兩個概念並沒有讓開發做原來JS+CSS+HTML做不了的事,而是解決開發粒度的問題,讓前端有一個清晰的從高到低的設計與架構框架,高就是設計Component的拓撲,低就是每個Component的內部實現。
這兩個概念也並不新鮮,只不過在用jQuery Plugin做前端的時代,還沒有產生這種清晰的架構思路,主要關注形成功能,一個功能塊的模塊化完全模塊化必須依賴JS或者某種預編譯工具,有了Component和Declarative的概念,開發的思考起點跟清楚了,更重要的是,團隊開發的一致性應該會更好,依據Component的模塊化對測試與部署也是很有用的。
這不會因為使用angular 2還是React有很大不同。
兩個我個人都喜歡,都好用,不夠我可能更偏向angular 2一點,雖然不認為React會因此消失。碰到這樣的問題,我的一般回答都是「都看都學也無妨」,互為映襯能融合視角。
我沒什麼特別有說服力的理由,不夠直覺上angular 2的實現自然一點,Component templating是100%的HTML,相比React的JSX語法覺得沒有使用上的奇怪感覺,倒也不是有多難用。因為框架里有許多黑魔法,這樣我可以把注意力放在設計好Component本身身上,而不需要額外花精力關注如何使用這個Component,比如angular 2讓你關注需要render的template,而不是render的過程,這樣能更快地產生比較好的Component封裝。angular 2的移動native支持還弱一點,但按照google的實力,我想並不需要擔心在不久的將來它的移動native端應用能力會比react native弱多少,況且angular 2是可以和reactive native集成的。
總的來說,我覺得不太會是一邊倒的情況,angular 2是值得看的。Angular、Vue、React 和前端的未來
其實個人感覺前端讓人很困惑,隨意吐幾個槽吧。1.react 寫proptypes一度讓我覺得很煩惱,因為我的項目並不需要太多復用components,但是我看不得lint報錯。2.類型系統的缺失也很煩惱,有時候期望一個強大的類型系統,有些問題確實是很trivial而且時不時跳出來感覺就是很煩。毫無疑問最好就是上typescript,但是我內心是想上scalajs的。3.angular的作用範圍和react其實不太相同,angular寫著很快啊,寫crud簡直突出一個快。官方網站也是推薦寫crud(我記得是這樣的。
4.react flux寫起來真的很啰嗦,竟然都沒有人吐槽。唯一見@尤雨溪吐槽過redux,的確是很繁瑣。我如果mvc就搞個model,vc混寫寫小東西喝喝茶就寫完了。react的話,要寫action-&>action creator-&>reducer/dispatcher-&>react component,這只是一個交互操作,如果是非同步請求還要*3。(寫action常量不是我想要的生活。
5.react好處是需求變更,可以亂改坑不是很大。6.react寫得煩躁的時候就會想偷懶,全局狀態啊,不在action裡面非同步啊,把別的插件包個react皮膚就上啊。重要的還是要有review啊。7.所以我想吐槽的是,搬磚的時候重要的都是deadline。如果ddl需要,react配個eventEmitter寫起來最快了。8.0.13到0.14有天刪了一下node_modules,然後重新安裝,好幾個包都不認識了。====更新內容====
如何工程化開發大型angular2項目(上篇續)(分享自知乎網)https://zhuanlan.zhihu.com/p/24545021如何工程化開發大型angular2項目(上篇)(分享自知乎網)http://zhuanlan.zhihu.com/p/23808621===============淺談一下從3月份到現在用angular2的體驗。alpha版到rc.7,之間變動之大。router系統重構好幾版,component組件編寫語法也是變了好幾次。上頭追新,作死應用到生產環境,應用越做越大,打包出來JS都快2、3M。導致客戶普遍抱怨首屏載入慢。還好後來在Nginx伺服器上做了優化,還有angular提供了預編譯技術,先渲染HTML。速度提升60%。這裡也不是抱怨angular小組技術變動大,畢竟還是研發階段。我想提一點是,追求新技術是值得鼓勵的,但是不要把還在研發的技術應用在主線產品中,而是用在一些內部系統中。不然真是血的教訓。
當然要說說,angular這次變革式創新出了2代。優勢有1.學習成本降低,因為有中文版文檔www. angular.cn,在也不用聽新同學抱怨英文看不懂。基本看幾天就能上手。會angular2,看vue基本無壓力,反過來也行得通。2.技術實現成本降低,用angular1實現組件共用,用2輕鬆實現。現在項目里已經有很多通用組件了。3.react,vue的redux,angular2也有,ngrx技術。4.對於選擇恐懼症的盆友,angular2真是一站式服務。5.聽說react可以開發native app,不好意思angular2和nativescript也可以開發原生app。 忘了說一句,angular2還可以開發react native。(自行上GitHub搜索angular2 react native).6.最六的是支持Rx.JS。7.人生苦短,快用angular2吧。PS:哪有蘿蔔坑,準備挪坑,私聊本人從事前端工作也有差不多10年,我一直認為這些框架都是工具,最討厭為了一種新技術放棄整體效果和用戶體驗,對前端來說最重要的還是創意和思想。框架這些東西好比食材,真正價值在於廚師的廚藝,即使用上個時代的bootstrap tweenmax也可以製作美好的桌面作品。有人說ng1有多垃圾,vue有多優雅,悠悠眾口眾說紛紜,我是懶得去聽,前端工程師常犯的錯,就是追求新潮,忽略了技術要為社會服務這個基本的常識,心態焦慮而急躁,生怕被時代拋棄,失去競爭力,或者抱著投機致富的心態。我常對同行說,不要炫技,老老實實寫代碼。前端的未來,不在投入哪個門派,不在採用哪個框架,而是你能不能真正解決問題,你的數萬個工具在一起是否和諧,你的代碼是否健壯這些基本的東西。
以社區志願者的心態,寫了angular2和react+redux的實例系列教程,目前為止,react+redux教程的star零頭都比angular2教程多
GitHub - lewis617/angular2-tutorial: angular2-tutorial in Chinese
GitHub - lewis617/react-redux-tutorial: react-redux-tutorial in Chinese ,catalogcode examples吐槽一下:Redux框架實現伺服器端渲染是個餿主意,以下這個boilerplate沒人吐槽,不科學啊!就是這個東東,react-redux-universal-hot-example,坑連坑啊,坑爹的貨!裡面有個核心模塊叫redux-async-connect,開發者已經放棄更新了,而且這個模塊沒有說明文檔!還有個更坑爹的模塊叫 redux-form,裡面的開發者文檔也是《九陰真經》風格的!react-redux-universal-hot-example 這個模塊我花了近半年時間才基本搞明白,結論是伺服器端基於Redux技術的渲染是個糟糕的注意,還不如直接寫PHP。我現在安心使用Anglar2了。
其實不管前端還是後端,,方向一致沒變,大而全的框架很難真正的一直流行下去。但是小而美的框架在流行之後又很容易走上大而全。。
後端有j2ee之於ejb-&>spring,hibernate-&>mybatis等等這些技術變遷!就跟現在後端流行的微服務一樣,設計精巧,可以比較好的與其他技術兼容。
不管你怎麼吐槽jquery,backbone這些類庫或者簡單框架,但是很明顯他們本身沒有很明顯問題,而且很容易和其他框架結合起來,,,我相信在一段時間之內至少jquery,還會存在併流行下去.
vue流行起來不也是小而美的原因,如果他一開始就做angular模仿著,我相信幾乎很難流行起來..
angular有他的市場,有他合適的場景,但很難說是前端的方向,,
react列,我很難評論,前端一直以來不就是合久必分,分久必合.適合自己,適合團隊,打好基礎才是實在.前端未來的方向是精通js
換個視角來看問題,如果問題主體是前端的未來,那與Angular關係不是特別大,與React關係大點。
建議大家認真想下,別只看字數長回答,大部分有想法有遠見的人沒那麼多時間來編輯巨長無比的答案!fis和其生態也可以算一種吧
ng2 + rx.lite min之後700K+,大小是react + redux + ng1 + ember 的總和左右,你感受下
angular 和 react, 知識js發展的其中一個很小的階段而已,和後端語言一樣,指不定那天會有新的東西出來代替,作為開發著,保持擁抱學習的心裡,懂得Js基礎知識,不管啥框架出來,很快都可以消化,每個框架都有它存在的理由,沒有必要偏向於哪個框架,沒有好不好,是有適合不適合。
用了React簡潔的JSX syntax以後再也不想用Angular那個繁瑣的directive了。話說JSX要是能跟TypeScript,Webpack結合起來就好了。雖然現在也可以這麼做,但是Facebook推薦跟react一起用的是Flow,而不是typescript,還是觀望一下Flow的發展吧。
原生js是未來方向!
React vs Angular 2: 戰爭繼續
by ouven
2016年04月07日 in Article-translationReact vs Angular 2: 戰爭繼續React vs Angular 2: 戰爭繼續【原譯】: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,它體現了兩者很多方面的亮點,第一次對決已經結束,但是大戰才剛剛開始。(譯者註:老外寫個文章真的一定要這麼誇張嗎?哈哈~)
認清你的對手作為開發者,選擇angular還是react就像購買現成的電腦還是用現成的零件來組裝電腦一樣。
Cory House告訴我們:
angular 2React壓縮後764K壓縮後151k獨立的完整解決方案簡單的視圖庫很多angular特定的語法javascript語法很好的一致性(和typescript)基本語法有點混淆使用html和jsjsx語法綜合成熟穩定的框架發展迅速的開源庫手動debug,缺少完全的支持jsx-很好的開發體驗對web components友好有可能支持web componnets靜態執行jsx-動態執行我想補充的是react有很多優秀的瀏覽器開發插件,然而並沒有看到angular 2的。
競技場為了比較這些前端的技術,我做了一些TODO應用。為了使問題更加簡單,我在兩個應用中只使用了Redux core(受angular 2-introduction to Redux啟發)。兩個都是使用typescript開發的,所以比較起來比較清晰些。你可以對比下代碼:
– Redux Core: GitHub - evojam/redux-todo-lib: Redux – Angular2 App: GitHub - evojam/angular2-redux-sample-app: Angula2 Redux – React App: GitHub - evojam/react-redux-sample-app: ReactJS Redux
對抗兩者的核心都是一個component或是一個view單元。兩個都將你的app形成一個組件樹。它們都鼓勵將數據通過頂層傳遞給組件樹。根到葉子的數據流思路使我們開發的應用」更靈活」,所以現在開始。
第一輪:功能組件在這個樹形結構的基礎應用中,每個頂層樹是一個組件,每個組件的特點:
- 從父節點接受數據(稱之為輸入)
- 返回一個組件的子樹(視圖view)
在angular2和React中,輸入都是通過子節點屬性(不是html屬性)從一個元素傳遞到它的子樹,兩種解決方案中,視圖view都可以理解為xml樹。
TodoList組件一個可復用、可選擇、簡單的todo list需要做到兩點–todos數組(我做的數組)和過濾的方式(要展示的數組)。所以我們的組件輸入可以是這樣的:
interface ITodoListProps {
todos: ITodo[];
filter: FilterType;
}
而組件在任何地方都可以這樣使用:
– React
&
–Angular 2
&
- &
下面是React組件的定義:
// src/components/todo-list.tsx
import { Todo } from "./todo";
export function TodoList(props: ITodoListProps): JSX.Element {
return (
&
-
{todosFilter(props.todoList, props.filter)
.map(todo =&> (
&
))}
&
}
下面是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
&
&
毫無疑問,React版本是沒有狀態,更純正,更簡單,它使用data並返回dom,很好。
這裡可以運行但是不能正確編譯,我不知道它是不是typescript支持性的原因或者React編碼輸入的錯誤(如果知道錯誤請給issue)。無論怎樣,它失敗了,我不得不在React組件基礎上切換成一個class。React保存了狀態–就是組件成員的屬性–但是屬性仍然可以被當做immutable的數據輸入:
// src/components/todo-list.tsx
import { Todo } from "./todo";
export class TodoList extends Component&
render(): JSX.Element {
return (
&
-
{todosFilter(this.props.todoList, this.props.filter)
.map(todo =&> &
&
}
}
angular2 版本需要多得多的配置,對於這個簡單的應用要乾的事情太多了。這是因為angular沒有將js和html混合在一起(directives,host,pipes,selector,templateUrl)和更多複雜的數據修改檢測機制(數據監聽)。
- selector是一種將組件js定義和模板元素綁定起來的方法–而在React它不需要因為js組件就是jsx組件元素。
- pipes和directives用於通知組件哪些其它的組件、directives和pipes(內置html filter)將要在模板中使用,而React中的js組件是直接在jsx模板中使用的。React不提供任何無模板的directive(對我來說這是個問題,我後面會提到)或者內聯的pipes(因為我們可以使用純js功能)。
- templateUrl是大家都明白的,對吧?它被因為是線下引用的,但是我確實覺得從組件文件中分離出更大的模板是比較合理的做法。缺少實時編譯的模板檢查確實是angular的劣勢。
- 而host的出現是因為模板渲染中過程不大一樣
React的組件功能(或是渲染方法)返回整個頂層模板包含的組件樹。
return (
&
-
{ todoList.map( todo =&> &
&
在angular中,組件是與組件的根元素綁定的(通過上面提到的選擇器selector),這個組件的根元素就被稱為host,所以在angular模板中,我們只放入根元素的內容:
// src/components/todo-list.html
&
如果我們想添加一下東西(例如css的class,屬性值)給host元素,我們稱之為host定義,例如 {"class":"todo-list"} 會添加 todo-list類到&
- &
所以我們現在開始綁定一些事件處理器。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
&
&
&
我們把ITodo實例當做一個輸入值。輸出為帶有兩個按鈕的host元素。我們也綁定了靜態todo和條件的"done"css類到host元素中。按鈕點擊觸發組件的todoActions成員相應的方法。沒什麼亮點,只有(click)=...或許會引起我們的注意。我們也可以」加點糖「並使用&
而React版本:
interface ITodoProps {
todo: ITodo;
key: string;
}
export class Todo extends Component&
private getToggleAction(todo: ITodo) {
return () =&> {
todoActions.toggleTodo(todo.id);
}
}
private removeTodo(todo: ITodo) {
todoActions.removeTodo(this.props.todo.id);
}
public render(): JSX.Element {
return (
&
&
&
}
}
我們把ITodo實例當做一個輸入值。輸出為帶有兩個按鈕的一個元素。XML樹返回的根元素也綁定了靜態todo和條件的"done"css類。目前為止都基本相似。但是我們看到這裡兩個React令人失望的特點:
- 在onClick處理中this的上下文丟失了–我們必須做下修改(綁定或添加)
- class屬性必須和整個元素一起保存–沒有css類管理機制
我也不喜歡className和htmlFor屬性,但是他們必須要使用,因為class和For都是js的保留字,就像我們必須將html和js混合在一起一樣。
組合:ReactTodo
&
&
&
TodoList
&
-
{ todoList.map( todo =&> &
&
對於對象更深的結構:
&
輸出為:
&
-
&
-
&
&
&
…
&
組合:Angular2
Todo
@Component({ host: {"class": "todo"}, selector: "[todo]", … })
export class Todo … {
…
@HostBinding("class.done")
private get isCompleted() { … }
}
&
&
TodoList
@Component({ host: {"class":"todo-list"}, selector: "[todoList]", … })
export class TodoList … { … }
&
&
對於對象更深的結構:
&
- &
輸出為:
&
- &
-
&
&
&
…
&
&
第一輪結果
React在開發輕量級單一組件場景下具有絕對優勢。如果你的應用可以用數據視圖簡單描述清楚的話React似乎是最佳的解決方案。而且無疑是我們見過的最靈活的視圖渲染框架。但是事件處理邏輯越多,UI渲染越複雜,angular2就越具有優勢。事實上,angular2的組件配置和綁定聲明複雜度和組件的複雜性成反比。此外,它還有靈活的使用方式(從數據到視圖的綁定)。可能某一天Reactangular或者Angulareact框架能讓我們高效的在一個應用中使用兩種實現方式。但現在我們必須要選擇。
靈活與否,都應該以減輕開發者的痛苦來作為考量。代碼的可讀性也是一方面,但目前html在這裡是很重要的判斷。
第二輪:視圖美學讓我們來準備一個新的組件來處理更複雜的結構–列表結構。
angular2
&
&
-
&
-
&
&
&
&
React
&
-
{this.props.lists.map(list =&> (
&
{list.id !== this.props.currentId ? (
&-
{list.todos.map(todo =&> (
{todo.text}
&
))}
&
&
&
)}
&
))}
&
&
第二輪結果
有什麼好說的嗎?選擇你喜歡的就好了~
ok,我認為&
我們在此聲明一件重要的事情–Dom修改(在修改被檢測到以後)在兩種框架中處理方式是類似的。它們只修改確實需要改變的部分。我們來看下如果發生數據變化,處理的方式有什麼不同;
React
React的基本處理方式很簡單。如果組件的state或者props發生改變,就會調用修改處理函數:
- state在setState()被調用時觸發
- props在父組件重新渲染時發生變化
當然也可以通過調用forceUpdate()來觸發改變,修改監聽器只在子樹發生改變的地方觸發。簡單便捷,唯一不好的地方是我們必須在頂層元素裏手動調用setState()方法。
你可能會注意到例子裡面的key={todo.id},這裡是來列表元素檢測改變的機制必須的,如果一個key上面的值修改了–html相對應的元素就會重新渲染。有點啰嗦,但是有必要。另外在項目中使用嚴格模式編程是,你必須在你的列表組件中額外定義一個key:string。
Angular
angular 團隊決定使用稍微不同的方式。他們包含了zone.js到瀏覽器非同步回調中(例如:setTimeout,setInterval,事件處理和xhr請求事件)。當他們當中任意一個被調用,就會運行修改檢測。你可參考下great in-depth explanation,更有趣的是,你可以在你任意一個組件樹上選擇使用的檢測策略。
在樣例中,我使用了onPush策略,所以所有的組件修改檢測只在他們@input()屬性發生變化時才會觸發。所以angular里的修改檢測可以在任何合適的時候觸發,而react只在一個時候觸發。當然angular還有更多的觸發策略:CheckOnce, Checked, CheckAlways, Detached, OnPush, Default。跟多信息可以參考:ChangeDetectionStrategy docs。
就像React的key={…}一樣,angular有自己的方式來處理列表的變化–NgFor.ngForTrackBy。在代碼里就是&
兩種解決方案都提供了一個相對健全的途徑,然而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 { … }
}
上面的例子展示了我們怎樣從一個輸入屬性中獲取值、綁定一些其他值給元素屬性或給元素添加監聽事件。而且它可以用inp-alerter屬性應用到其它任意一個html元素中。而且這只是我們能做的很小的一部分,實際上@Directive定義的類可以作為絕大多數功能用於@components,但是沒有模板。簡單強大。
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的經歷來看它具有更加優秀的合併思想。
譯者:ouven
原文作者:JAKUB STROJEWSKI
這裡只有強烈安利一下我這個項目了GitHub - bodyno/react-starter-kit: 完美使用 React, Redux, and React-Router!用了之後 你就會發現 你什麼都懂了
一直等polymer一統天下 等的我都轉行寫iOS了 沒想到還得寫react native
推薦閱讀:
※為什麼 CSS :not 選擇器不支持複雜選擇?
※985待業半年多,想去做前端,不知道現在還行嗎?
※25歲如花的年紀自學前端是明智的選擇么? 這幾天正猶豫要不要辭職,希望知友能給點意見,先行謝過?
※花整個大學的時間研究前端好嗎?
※如何評價阮一峰關於前端工具變化快的言論?