這個頁面無疑是最難編寫的,但咱們認爲它也是很是重要的。或許你曾遇到了一些問題而且已經用其餘的框架解決了。你來這裏的目的是看看 Vue 是否有更好的解決方案。這也是咱們在此想要回答的。css
客觀來講,做爲核心團隊成員,顯然咱們會更偏心 Vue,認爲對於某些問題來說用 Vue 解決會更好。若是沒有這點信念,咱們也就不會成天爲此忙活了。可是在此,咱們想盡量地公平和準確地來描述一切。其餘的框架也有顯著的優勢,例如 React 龐大的生態系統,或者像是 Knockout 對瀏覽器的支持覆蓋到了 IE6。咱們會嘗試着把這些內容所有列出來。html
咱們也但願獲得你的幫助,來使文檔保持最新狀態,由於 JavaScript 的世界進步的太快。若是你注意到一個不許確或彷佛不太正確的地方,請提交問題讓咱們知道。vue
React 和 Vue 有許多類似之處,它們都有:react
因爲有着衆多的類似處,咱們會用更多的時間在這一塊進行比較。這裏咱們不僅保證技術內容的準確性,同時也兼顧了平衡的考量。咱們須要認可 React 比 Vue 更好的地方,好比更豐富的生態系統。webpack
React 社區爲咱們準確進行平衡的考量提供了很是積極的幫助,特別感謝來自 React 團隊的 Dan Abramov 。他很是慷慨的花費時間來貢獻專業知識來幫助咱們完善這篇文檔。git
React 和 Vue 都是很是快的,因此速度並非在它們之中作選擇的決定性因素。對於具體的數據表現,能夠移步這個第三方 benchmark,它專一於渲染/更新很是簡單的組件樹的真實性能。github
在 React 應用中,當某個組件的狀態發生變化時,它會以該組件爲根,從新渲染整個組件子樹。web
如要避免沒必要要的子組件的重渲染,你須要在全部可能的地方使用 PureComponent
,或是手動實現 shouldComponentUpdate
方法。同時你可能會須要使用不可變的數據結構來使得你的組件更容易被優化。vuex
然而,使用 PureComponent
和 shouldComponentUpdate
時,須要保證該組件的整個子樹的渲染輸出都是由該組件的 props 所決定的。若是不符合這個狀況,那麼此類優化就會致使難以察覺的渲染結果不一致。這使得 React 中的組件優化伴隨着至關的心智負擔。vue-cli
在 Vue 應用中,組件的依賴是在渲染過程當中自動追蹤的,因此係統能精確知曉哪一個組件確實須要被重渲染。你能夠理解爲每個組件都已經自動得到了 shouldComponentUpdate
,而且沒有上述的子樹問題限制。
Vue 的這個特色使得開發者再也不須要考慮此類優化,從而可以更好地專一於應用自己。
在 React 中,一切都是 JavaScript。不只僅是 HTML 能夠用 JSX 來表達,如今的潮流也愈來愈多地將 CSS 也歸入到 JavaScript 中來處理。這類方案有其優勢,但也存在一些不是每一個開發者都能接受的取捨。
Vue 的總體思想是擁抱經典的 Web 技術,並在其上進行擴展。咱們下面會詳細分析一下。
在 React 中,全部的組件的渲染功能都依靠 JSX。JSX 是使用 XML 語法編寫 JavaScript 的一種語法糖。
JSX 說是手寫的渲染函數有下面這些優點:
你可使用完整的編程語言 JavaScript 功能來構建你的視圖頁面。好比你可使用臨時變量、JS 自帶的流程控制、以及直接引用當前 JS 做用域中的值等等。
開發工具對 JSX 的支持相比於現有可用的其餘 Vue 模板仍是比較先進的 (好比,linting、類型檢查、編輯器的自動完成)。
事實上 Vue 也提供了渲染函數,甚至支持 JSX。然而,咱們默認推薦的仍是模板。任何合乎規範的 HTML 都是合法的 Vue 模板,這也帶來了一些特有的優點:
對於不少習慣了 HTML 的開發者來講,模板比起 JSX 讀寫起來更天然。這裏固然有主觀偏好的成分,但若是這種區別會致使開發效率的提高,那麼它就有客觀的價值存在。
基於 HTML 的模板使得將已有的應用逐步遷移到 Vue 更爲容易。
這也使得設計師和新人開發者更容易理解和參與到項目中。
你甚至可使用其餘模板預處理器,好比 Pug 來書寫 Vue 的模板。
有些開發者認爲模板意味着須要學習額外的 DSL (Domain-Specific Language 領域特定語言) 才能進行開發——咱們認爲這種區別是比較膚淺的。首先,JSX 並非免費的——它是基於 JS 之上的一套額外語法,所以也有它本身的學習成本。同時,正如同熟悉 JS 的人學習 JSX 會很容易同樣,熟悉 HTML 的人學習 Vue 的模板語法也是很容易的。最後,DSL 的存在使得咱們可讓開發者用更少的代碼作更多的事,好比 v-on
的各類修飾符,在 JSX 中實現對應的功能會須要多得多的代碼。
更抽象一點來看,咱們能夠把組件區分爲兩類:一類是偏視圖表現的 (presentational),一類則是偏邏輯的 (logical)。咱們推薦在前者中使用模板,在後者中使用 JSX 或渲染函數。這兩類組件的比例會根據應用類型的不一樣有所變化,但總體來講咱們發現表現類的組件遠遠多於邏輯類組件。
除非你把組件分佈在多個文件上 (例如 CSS Modules),CSS 做用域在 React 中是經過 CSS-in-JS 的方案實現的 (好比 styled-components、glamorous 和 emotion)。這引入了一個新的面向組件的樣式範例,它和普通的 CSS 撰寫過程是有區別的。另外,雖然在構建時將 CSS 提取到一個單獨的樣式表是支持的,但 bundle 裏一般仍是須要一個運行時程序來讓這些樣式生效。當你可以利用 JavaScript 靈活處理樣式的同時,也須要權衡 bundle 的尺寸和運行時的開銷。
若是你是一個 CSS-in-JS 的愛好者,許多主流的 CSS-in-JS 庫也都支持 Vue (好比 styled-components-vue 和 vue-emotion)。這裏 React 和 Vue 主要的區別是,Vue 設置樣式的默認方法是單文件組件裏相似 style
的標籤。
單文件組件讓你能夠在同一個文件裏徹底控制 CSS,將其做爲組件代碼的一部分。
<style scoped> |
這個可選 scoped
屬性會自動添加一個惟一的屬性 (好比 data-v-21e5b78
) 爲組件內 CSS 指定做用域,編譯的時候 .list-container:hover
會被編譯成相似.list-container[data-v-21e5b78]:hover
。
最後,Vue 的單文件組件裏的樣式設置是很是靈活的。經過 vue-loader,你可使用任意預處理器、後處理器,甚至深度集成 CSS Modules——所有都在 <style>
標籤內。
Vue 和 React 都提供了強大的路由來應對大型應用。React 社區在狀態管理方面很是有創新精神 (好比 Flux、Redux),而這些狀態管理模式甚至 Redux 自己也能夠很是容易的集成在 Vue 應用中。實際上,Vue 更進一步地採用了這種模式 (Vuex),更加深刻集成 Vue 的狀態管理解決方案 Vuex 相信能爲你帶來更好的開發體驗。
二者另外一個重要差別是,Vue 的路由庫和狀態管理庫都是由官方維護支持且與核心庫同步更新的。React 則是選擇把這些問題交給社區維護,所以建立了一個更分散的生態系統。但相對的,React 的生態系統相比 Vue 更加繁榮。
最後,Vue 提供了Vue-cli 腳手架,能讓你很是容易地構建項目,包含了Webpack,Browserify,甚至 no build system。React 在這方面也提供了create-react-app,可是如今還存在一些侷限性:
而要注意的是這些限制是故意設計的,這有它的優點。例如,若是你的項目需求很是簡單,你就不須要自定義生成過程。你能把它做爲一個依賴來更新。若是閱讀更多關於不一樣的設計理念。
React 學習曲線陡峭,在你開始學 React 前,你須要知道 JSX 和 ES2015,由於許多示例用的是這些語法。你須要學習構建系統,雖然你在技術上能夠用 Babel 來實時編譯代碼,可是這並不推薦用於生產環境。
就像 Vue 向上擴展比如 React 同樣,Vue 向下擴展後就相似於 jQuery。你只要把以下標籤放到頁面就能夠運行:
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
而後你就能夠編寫 Vue 代碼並應用到生產中,你只要用 min 版 Vue 文件替換掉就不用擔憂其餘的性能問題。
因爲起步階段不需學 JSX,ES2015 以及構建系統,因此開發者只需不到一天的時間閱讀指南就能夠創建簡單的應用程序。
React Native 能使你用相同的組件模型編寫有本地渲染能力的 APP (iOS 和 Android)。能同時跨多平臺開發,對開發者是很是棒的。相應地,Vue 和 Weex 會進行官方合做,Weex 是阿里的跨平臺用戶界面開發框架,Weex 的 JavaScript 框架運行時用的就是 Vue。這意味着在 Weex 的幫助下,你使用 Vue 語法開發的組件不只僅能夠運行在瀏覽器端,還能被用於開發 iOS 和 Android 上的原生應用。
在如今,Weex 還在積極發展,成熟度也不能和 React Native 相抗衡。可是,Weex 的發展是由世界上最大的電子商務企業的需求在驅動,Vue 團隊也會和 Weex 團隊積極合做確保爲開發者帶來良好的開發體驗。
另外一個 Vue 的開發者們很快就會擁有的選項是 NativeScript,這是一個社區驅動的插件。
Mobx 在 React 社區很流行,實際上在 Vue 也採用了幾乎相同的反應系統。在有限程度上,React + Mobx 也能夠被認爲是更繁瑣的 Vue,因此若是你習慣組合使用它們,那麼選擇 Vue 會更合理。
Vue 的一些語法和 AngularJS 的很類似 (例如 v-if
vs ng-if
)。由於 AngularJS 是 Vue 早期開發的靈感來源。然而,AngularJS 中存在的許多問題,在 Vue 中已經獲得解決。
在 API 與設計兩方面上 Vue.js 都比 AngularJS 簡單得多,所以你能夠快速地掌握它的所有特性並投入開發。
Vue.js 是一個更加靈活開放的解決方案。它容許你以但願的方式組織應用程序,而不是在任什麼時候候都必須遵循 AngularJS 制定的規則,這讓 Vue 能適用於各類項目。咱們知道把決定權交給你是很是必要的。
這也就是爲何咱們提供 webpack template,讓你能夠用幾分鐘,去選擇是否啓用高級特性,好比熱模塊加載、linting、CSS 提取等等。
AngularJS 使用雙向綁定,Vue 在不一樣組件間強制使用單向數據流。這使應用中的數據流更加清晰易懂。
在 Vue 中指令和組件分得更清晰。指令只封裝 DOM 操做,而組件表明一個自給自足的獨立單元——有本身的視圖和數據邏輯。在 AngularJS 中二者有很多相混的地方。
Vue 有更好的性能,而且很是很是容易優化,由於它不使用髒檢查。
在 AngularJS 中,當 watcher 愈來愈多時會變得愈來愈慢,由於做用域內的每一次變化,全部 watcher 都要從新計算。而且,若是一些 watcher 觸發另外一個更新,髒檢查循環 (digest cycle) 可能要運行屢次。AngularJS 用戶經常要使用深奧的技術,以解決髒檢查循環的問題。有時沒有簡單的辦法來優化有大量 watcher 的做用域。
Vue 則根本沒有這個問題,由於它使用基於依賴追蹤的觀察系統而且異步隊列更新,全部的數據變化都是獨立觸發,除非它們之間有明確的依賴關係。
有意思的是,Angular 和 Vue 用類似的設計解決了一些 AngularJS 中存在的問題。
咱們將新的 Angular 獨立開來討論,由於它是一個和 AngularJS 徹底不一樣的框架。例如:它具備優秀的組件系統,而且許多實現已經徹底重寫,API 也徹底改變了。
Angular 事實上必須用 TypeScript 來開發,由於它的文檔和學習資源幾乎所有是面向 TS 的。TS 有不少好處——靜態類型檢查在大規模的應用中很是有用,同時對於 Java 和 C# 背景的開發者也是很是提高開發效率的。
然而,並非全部人都想用 TS——在中小型規模的項目中,引入 TS 可能並不會帶來太多明顯的優點。在這些狀況下,用 Vue 會是更好的選擇,由於在不用 TS 的狀況下使用 Angular 會頗有挑戰性。
最後,雖然 Vue 和 TS 的整合可能不如 Angular 那麼深刻,咱們也提供了官方的 類型聲明 和組件裝飾器,而且知道有大量用戶在生產環境中使用 Vue + TS 的組合。咱們也和微軟的 TS / VSCode 團隊進行着積極的合做,目標是爲 Vue + TS 用戶提供更好的類型檢查和 IDE 開發體驗。
這兩個框架都很快,有很是相似的 benchmark 數據。你能夠瀏覽具體的數據作更細粒度的對比,不過速度應該不是決定性的因素。
在體積方面,最近的 Angular 版本中在使用了 AOT 和 tree-shaking 技術後使得最終的代碼體積減少了許多。但即便如此,一個包含了 Vuex + Vue Router 的 Vue 項目 (gzip 以後 30kB) 相比使用了這些優化的 angular-cli
生成的默認項目尺寸 (~130kB) 仍是要小得多。
Vue 相比於 Angular 更加靈活,Vue 官方提供了構建工具來協助你構建項目,但它並不限制你去如何組織你的應用代碼。有人可能喜歡有嚴格的代碼組織規範,但也有開發者喜歡更靈活自由的方式。
要學習 Vue,你只須要有良好的 HTML 和 JavaScript 基礎。有了這些基本的技能,你就能夠很是快速地經過閱讀 指南 投入開發。
Angular 的學習曲線是很是陡峭的——做爲一個框架,它的 API 面積比起 Vue 要大得多,你也所以須要理解更多的概念才能開始有效率地工做。固然,Angular 自己的複雜度是由於它的設計目標就是隻針對大型的複雜應用;但不能否認的是,這也使得它對於經驗不甚豐富的開發者至關的不友好。
Ember 是一個全能框架。它提供了大量的約定,一旦你熟悉了它們,開發會變得很高效。不過,這也意味着學習曲線較高,並且並不靈活。這意味着在框架和庫 (加上一系列鬆散耦合的工具) 之間作權衡選擇。後者會更自由,可是也要求你作更多架構上的決定。
也就是說,咱們最比如較的是 Vue 內核和 Ember 的模板與數據模型層:
Vue 在普通 JavaScript 對象上創建響應,提供自動化的計算屬性。在 Ember 中須要將全部東西放在 Ember 對象內,而且手工爲計算屬性聲明依賴。
Vue 的模板語法能夠用全功能的 JavaScript 表達式,而 Handlebars 的語法和幫助函數相比來講很是受限。
在性能上,Vue 比 Ember 好不少,即便是 Ember 2.x 的最新 Glimmer 引擎。Vue 可以自動批量更新,而 Ember 在性能敏感的場景時須要手動管理。
Knockout 是 MVVM 領域內的先驅,而且追蹤依賴。它的響應系統和 Vue 也很類似。它在瀏覽器支持以及其餘方面的表現也是讓人印象深入的。它最低能支持到 IE6,而 Vue 最低只能支持到 IE9。
隨着時間的推移,Knockout 的發展已有所放緩,而且略顯有點老舊了。好比,它的組件系統缺乏完備的生命週期事件方法,儘管這些在如今是很是常見的。以及相比於 Vue 調用子組件的接口它的方法顯得有點笨重。
若是你有興趣研究,你還會發現兩者在接口設計的理念上是不一樣的。這能夠經過各自建立的simple Todo List 體現出來。或許有點主觀,可是不少人認爲 Vue 的 API 接口更簡單結構更優雅。
Polymer 是另外一個由谷歌贊助的項目,事實上也是 Vue 的一個靈感來源。Vue 的組件能夠粗略的類比於 Polymer 的自定義元素,而且二者具備類似的開發風格。最大的不一樣之處在於,Polymer 是基於最新版的 Web Components 標準之上,而且須要重量級的 polyfills 來幫助工做 (性能降低),瀏覽器自己並不支持這些功能。相比而言,Vue 在支持到 IE9 的狀況下並不須要依賴 polyfills 來工做。
在 Polymer 1.0 版本中,爲了彌補性能,團隊很是有限的使用數據綁定系統。例如,在 Polymer 中惟一支持的表達式只有布爾值否認和單一的方法調用,它的 computed 方法的實現也並非很靈活。
Polymer 自定義的元素是用 HTML 文件來建立的,這會限制使用 JavaScript/CSS (和被現代瀏覽器廣泛支持的語言特性)。相比之下,Vue 的單文件組件容許你很是容易的使用 ES2015 和你想用的 CSS 預編譯處理器。
在部署生產環境時,Polymer 建議使用 HTML Imports 加載全部資源。而這要求服務器和客戶端都支持 Http 2.0 協議,而且瀏覽器實現了此標準。這是否可行就取決於你的目標用戶和部署環境了。若是情況不佳,你必須用 Vulcanizer 工具來打包 Polymer 元素。而在這方面,Vue 能夠結合異步組件的特性和 Webpack 的代碼分割特性來實現懶加載 (lazy-loaded)。這同時確保了對舊瀏覽器的兼容且又能更快加載。
而 Vue 和 Web Component 標準進行深層次的整合也是徹底可行的,好比使用 Custom Elements、Shadow DOM 的樣式封裝。然而在咱們作出嚴肅的實現承諾以前,咱們目前仍在等待相關標準成熟,進而再普遍應用於主流的瀏覽器中。
Riot 3.0 提供了一個相似於基於組件的開發模型 (在 Riot 中稱之爲 Tag),它提供了小巧精美的 API。Riot 和 Vue 在設計理念上可能有許多類似處。儘管相比 Riot ,Vue 要顯得重一點,Vue 仍是有不少顯著優點的: