02.25 React 還是 Vue:選哪個?

在 2016 年,React 鞏固了自己 JavaScriptWeb 框架之王的地位。在那一年,它的 Web 和移動原生庫都經歷了快速增長,且明顯領先於其主要競爭對手 Angular。

但 2016 年對 Vue 來說也是值得紀念的一年。Vue 第二版發佈後在 JavaScript 社區中留下了深刻的印象,這一年中 Vue 新增的 25,000 個 Github 星星也證明了這一點。

毫無疑問,React 和 Vue 的目標市場非常相似:兩者都是基於組件的輕量級庫,都是用來構建僅關注視圖層的用戶界面。兩者都可以用在簡單的項目中,也可以使用頂尖的工具鏈擴展到複雜的應用程序上。

於是乎,許多 Web 開發人員都在猶豫到底該用哪個框架。它們之間有明顯的差距嗎?它們各自有什麼獨特的利弊需要注意的?還是說它們基本上沒什麼區別?

兩個框架,兩位粉絲

在這篇文章中,我想通過全面而公正的對比來回答這些問題。但這裡存在一個問題:我是一位狂熱的 Vue 粉絲,根本沒法拋棄自己的主觀意識做出客觀的決定。我在自己的眾多項目中大量使用 Vue,甚至發佈了一套在線課程,名為 UltimateVue.js 開發人員課程。

為了抵消我的偏見,我邀請了我的朋友 Alexis Mangin,他既是一位出色的 JavaScript 開發者,也是 React 的忠實粉絲。他也非常沉迷 React,經常在 Web 和移動項目中使用它。

有一天 Alexis 問我:“你為什麼這麼喜歡 Vue,而不是 React?”由於我不太瞭解 React,所以無法給出一個很好的答案。因此我跟他提了一個想法,就是說我們找一天帶著自己的筆記本坐下來聊聊,互相向對方展示我們中意的庫有哪些優點。

Anthony(左)和 Alexis(右)在泰國清邁的"公牛與熊"咖啡館對比 React 和 Vue

經過雙方的大量討論和學習,我們主要總結出了以下六點內容。


Vue:使用模板構建應用


將標記放入 HTML 文件中是 Vue 應用的默認選項。與 Angular 相似,花括號用於數據綁定表達式,而指令(特殊的 HTML 屬性)用來向模板添加功能。下面演示了一個簡單的 Vue 應用。它打出一條消息,並有一個可動態反轉這條消息的按鈕:


<code><divid>

{{ message }}

<click>Reverse Message/<click>/<divid>/<code>


<code>new Vue({el: '#app',data: {message: 'Hello Vue.js!},methods: {reverseMessage: function () {this.message= this.message.split('').reverse().join('');}}});/<code>

相反,React 應用會避開模板,並要求開發人員使用 JavaScript(通常在 JSX 的幫助下)創建 DOM。以下是使用 React 實現的同一個簡單應用:

<code><divid>/<code>

<code>classAppextendsReact.Component{constructor(props) {super(props);this.state = {message:'Hello React.js!'};}reverseMessage() {this.setState({message:this.state.message.split('').reverse().join('')});}render() {return(

{this.state.message}

<buttononclick>this.reverseMessage()}>Reverse Message/<buttononclick>
)}}ReactDOM.render(App,document.getElementById('app'));/<code>

對於熟悉 Web 開發標準範式的開發新手來說,模板更容易理解。而且一些頗有經驗的開發人員也喜歡它們,因為模板可以更好地分離佈局與功能,並可以選擇使用像 Pug 這樣的預處理器。

但模板的代價是必須學習所有擴展的 HTML 語法,而渲染函數就只需要瞭解標準 HTML 和 JavaScript 即可。渲染函數的好處還有更輕鬆的調試和測試過程。

在這一點上,選擇 Vue 是不會出問題的,因為它在版本 2 中同時引入了使用模板或渲染函數的選項。

Vue:簡單性 & “總之能用”

一個簡單的 Vue 項目可以無需轉譯(transpilation)就直接運行在瀏覽器裡。因此在項目中使用 Vue 就能像使用 jQuery 一樣容易。

儘管 React 從技術上來說也能做到這一點,但是典型的 React 代碼會相當依賴 JSX 和 ES6 功能(例如類和非可變數組方法)。但是 Vue 的簡單性是體現在其設計的更深層面中的。下面我們對比一下兩個庫是怎樣處理應用程序數據的(也就是“狀態”)。

React 中的狀態是不可變的,因此你無法直接更改它。你需要使用 setState API 方法:

<code>this.setState({message: this.state.message.split('').reverse().join('')});/<code>

React 會區分當前和先前的狀態,從而知道何時以及如何在 DOM 中重渲染,因此需要不可變狀態。

相反,數據在 Vue 中是會突變的。同樣的數據屬性在 Vue 中調整起來就簡潔得多:

<code>//Notethatdatapropertiesareavailableaspropertiesof//theVueinstancethis.message=this.message.split('').reverse().join('');/<code>

別急著下結論說 Vue 的渲染系統效率肯定不如 React 的,我們先來研究一下 Vue 中的狀態管理機制:當你向狀態添加一個新對象時,Vue 將遍歷其所有屬性並將它們轉換為 getter 和 setter。Vue 的反應系統現在可以跟蹤狀態,並在 DOM 突變時會自動重渲染。

令人印象深刻的是,在 Vue 中更改狀態不僅更簡潔,而且其重渲染系統實際上比 React 更快、更高效。

不過 Vue 的反應系統確實有一些不足。比如說,它無法檢測到屬性的添加或刪除以及某些數組更改。這些情況可以通過 Vue API 中類似 React 的 set 方法來解決。

Vue:如果你希望應用程序小而快

當應用狀態更改時,React 和 Vue 都會構建一個虛擬 DOM 並同步真實 DOM。兩者都有優化這一過程的手段。Vue 核心開發人員提供了一個基準測試,顯示 Vue 的渲染系統比 React 的更快。這個測試會對 10,000 個項目的列表渲染 100 次。對比成績如下表所示。

在 vuejs.org 上發佈的基準測試成績

從務實的角度來看,這種基準測試結果只能反映一些極端情況。大多數應用不需要頻繁執行此類操作,因此一般來說不應該把它當作是對比的重點

但是頁面大小是所有項目都要考慮的事情,而 Vue 再次佔據上風。Vue 庫的當前版本壓縮後只有 25.6KB。

為了在 React 中獲得類似的功能,你需要 ReactDOM(37.4KB)和 React 加擴展庫(11.4KB),總計 48.8KB,幾乎是 Vue 的兩倍。公平地說,React 的 API 更大,但功能卻沒有兩倍那麼多。

React:大型應用必備

對比 Vue 和 React 時,拿一個簡單應用的實現做比較(例如本文開頭的應用),可能會讓開發人員先入為主偏向 Vue。這是因為基於模板的應用乍看之下更容易理解,並且上手和運行起來也更快。

但這些看起來很棒的起步方式會引入一些技術債,進而在應用規模變大時拖累開發工作。模板容易出現很難發現的運行時錯誤,難以測試,並且不容易重構或解耦。

相比之下,JavaScript 製作的模板可以組織成解耦良好和使用 DRY 代碼的組件,這些代碼更容易重用和測試。

Vue 也有組件系統和渲染函數,但是 React 的渲染系統配置起來更自由,並且有淺層渲染等功能,可以結合 React 的測試工具來寫出更易測試和維護的代碼。

雖然 React 的不可變應用程序數據可能沒那麼簡潔,但是當較大的應用程序更看重透明性和可測試性時,它就會大放異彩。

React:同時適用於 Web 和原生應用的庫

ReactNative 是一個使用 JavaScript 構建原生移動應用程序的庫。它與 React.js 相同,只不過使用的是原生而非 Web 組件。如果你已經學會了 React.js,那麼就很容易入門 ReactNative,反之亦然。

<code>importReact, {Component} from'react';import{AppRegistry,Text,View} from'react-native';classHelloWorldextendsComponent{render() {return(<view><text>Hello,ReactNative!/<text>/<view>);}}AppRegistry.registerComponent('HelloWorld', () =>HelloWorld);/<code>

重點在於,開發人員用不著額外的知識和工具就可以在 Web 或原生移動設備上構建應用。如果你打算同時針對 Web 和移動端開發產品,那麼學習 React 將為你帶來巨大的收益。

阿里巴巴的 Weex 是另一個跨平臺的 UI 項目。目前,它認為 Vue 是一種“靈感”,並使用了許多相同的語法,並計劃完全集成 Vue。但這種整合工作的時間表和細節還不是很清楚

由於 Vue 將 HTML 模板作為其設計的一個核心部分,並且現有功能沒有支持自定義渲染,因此很難指望 Vue.js 在當前形式下會有一個像 React.js 和 React 那樣緊密的原生搭檔。

React:最大的生態系統

毫無疑問,React 是目前最受歡迎的庫,每月 NPM 下載約 250 萬次,而 Vue 每月約 22.5 萬。

人氣高的好處不僅僅那麼簡單。這同時意味著會有更多文章、教程和 StackOverflow 答案可提供幫助。這還意味著項目有更多工具和插件可供選擇,開發人員用不著自己構建所有內容。

這兩個庫都是開源的,但是 React 誕生於 Facebook,並從中受益。選擇 React 的開發人員和公司可以很放心,知道這個項目會長久維護下去。

相比之下,Vue 是由 Evan You 一位開發人員創建的,他目前是 Vue 的唯一全職維護者。Vue 有一些公司贊助,但規模不及 Facebook 或谷歌。

Vue 團隊值得稱道的是,它的小規模和獨立性尚未成為一種劣勢。Vue 有固定的發佈週期,而且更令人印象深刻的是,Vue 在 Github 上只有 54 個未解決問題,已解決問題多達 3456 個;而 React 有 530 個未解決問題,數量多得多,已解決問題是 3447 個。

如果你有所傾心則不必更換

回顧一下我們的討論結果,Vue 的優勢有:

靈活選擇模板或渲染函數。語法和項目設置簡單。渲染速度更快,尺寸更小。

React 的優勢:

更適合大應用,更健壯,更易測試。Web 和原生應用。更大的生態系統,支持和工具更多。

但 React 和 Vue 都是出色的 UI 庫,並且它們的相似之處多於差異。它們的大多數最佳特性都是類似的:

使用虛擬 DOM 進行快速渲染輕巧。反應性組件。服務端渲染。容易與路由器、打包器和狀態管理集成。很好的社區和支持。

如果你認為我們錯過了某些內容,希望在評論裡提出來。編程愉快!

Anthony Gore,JavaScript 開發人員和在線課程講師。博客名為 Vue.jsDevelopers,並且是 UltimateVue.js 開發課程的作者。

Alexis Mangin,Alexis 憑藉他在 Web 開發方面的卓越知識幫助作者撰寫了這篇文章。在 Medium 上撰寫許多關於 React 的精彩教程。

每天都會有更新看過的朋友可以點波關注,Java學習路線和優質資源評論或後臺回覆“Java”獲取