爲何咱們選擇Vue,而不選React(譯)

最近Qwintry團隊積極地把Vue.js做爲了他們的前端框架,而且在全部的新舊項目中使用它,包括:php

  • 過去qwintry.com的Drupal系統 (qwintry.com)css

  • 咱們的新項目,徹底重寫了qwintry.com分支html

  • 一個用Yii2 構建的B2B系統 (logistics.qwintry.com)前端

  • 咱們全部的小項目和外部拓展項目(大部分是php和node做爲後臺的)vue

世界上有大約被50W人使用Qwintry。咱們用咱們的軟件經營着兩個貨倉(一個在美國,一個在德國)。在美國,咱們是最大的郵件代理之一,咱們的用戶和貨運通道主要集中在東歐和中東。其實,咱們主要是幫助人們節約一些航運的費用,讓他們更方便的在網上購買美國的商品。而且咱們利用咱們的信息和物流系統,幫人們找到最好的性價比的商品。node

這是咱們在用戶門前的包裹。react

咱們擁有龐大的代碼庫,基本都是用PHP和JS構建的。ios

在咱們分別用React、Vue.js、Angular 2這些現代框架來構建咱們的「用戶計算器」以後,通過比較,咱們決定使用Vue.js。git

我對React的見解

當咱們在討論選擇前端框架的時候,React在JS世界的膨脹,致使了它如今極可能已經成爲JS開發者默認的選擇。github

我用React開發了一些SPA的應用,也作過一些動態的組件。我也在IOS下玩弄過RN + Redux。我以爲React對JS來講有一個偉大的出發點就是狀態機,它給人們展示了函數式編程的優點。我以爲RN的野心是龐大的,它改變了原生開發的世界。

對React的不足之處的我的看法

以一種純淨的、不變的、穩定的機制來控制狀態

別誤會,我很欣賞用純函數和簡單的render的方式控制狀態,毫無疑問,這在真實環境的生命週期中是一個很好的形式。我要討論的是其它的一些點。

我想,當你的團隊有超過1000個開發人員的時候,這種純淨的、嚴格的模式多是頗有必要的。但也只有當你想把你本身的語法加入到你寫的靜態規範的代碼的時候纔是必要的,或者你是一個從Haskell轉到JS的開發者。但大多數的開發團隊通常都是比Facebook小得多的開發團隊。

噁心的JSX

我懂我懂,它僅僅就只是一個特別的js語法。原本咱們的設計兼前端仔只須要去專一於每一行HTML的elements就好,然而他們如今寫代碼就像在吃shi。讓設計師使用JSX寫React組件是很是噁心的事情,由於JSX的可讀性太差了。不能在html代碼塊裏寫一些簡單的判斷語句,請別相信那些盲目的React粉絲告訴你,你不會須要寫這個,你只須要寫三元就好。我敢保證,在實際開發過程當中,你仍然須要讀寫一堆HTML和JS的混合代碼,即便他們後來被編譯成純JS。

 
    {items.map(item =>
  • {item.name} )} 複製代碼

    大量的開發者(曾經包括我)都以爲這是一個由特定限制的語法,這將會幫助你寫出更加模塊化的代碼,由於你不得不把你許多輔助方法也放入你的render函數裏,就像這傢伙的建議:
    stackoverflow.com/a/38231866/…

    也正是由於JSX的寫法,因此你不得不把15行的html代碼分割到三個組件中(每一個組件5行html)去。

    不要以爲這是可讓你成爲優秀開發者的一個好方法,由於其實你只是不得不像上面那樣編碼罷了。

    這裏有一些場景:

    當你在寫一個複雜組件(一個你可能並不會把它發佈在你的github上的組件)的時候,你爲了完成實際業務目標,你會拆分你的組件,而後組裝成一個更完善的大組件,由於JSX的數據規範可能會讓你的數據流溢出。但,個人意思不是說小組件很差或者效率不高。

    你應該清晰的意識到你把你的代碼分離到別的組件是爲了保持代碼的可讀性和可複用性。但你也應該知道,把你的代碼組件化是由於每一個組件他們有本身的邏輯實體,被分離後的組件有本身內部的屬性,(並且建議若是隻有兩三個 if 的時候建議寫三元表達式)。每次你建立了一個新的組件,都會消耗一些內存和一點點數據流(也可能更多),由於你須要從完成模塊業務的思路(當你肯定你已經記住了當前組件的狀態,而且你只須要添加一個html就能運行當前組件)切換到管理業務(管理組件)的思路上來。這樣你就能夠去分離組件,開始思考新組件的屬性,新組件如何去適應狀態,如何設計回調函數等等。

    事實上,由於在一個沒必要要的地方,強行權衡組件的模塊化過大或是太小的時候,會減慢你的編碼速度。在我看來,提早決定模塊化的方案就至關於提早決定了最佳實踐方案。

    對於我和個人團隊來講,代碼的可讀性是最重要的,可是代碼的趣味性也同樣很重要。試想,當你想要生效你的計算器插件須要用到6個組件,這樣的編碼並不有趣。而且在不少狀況下,一些插件代碼的維護、拓展或可視化測試,都要在好幾個文件或函數裏跳來跳去,而且須要檢查每一個被分離的html的小包是否正確運行。再次聲明,我不支持寫一個巨大的組件,我支持的是用組件去代替日復一日的微組件開發。這樣比較符合常識。

    用表單和Redux編碼將會讓你一成天都在歸類

    React是基於一個純淨的單向數據流的框架,記得嗎?這就是爲何 LinkedStateMixin 雙向綁定變得流行。如今,你必須建立10個函數得到10個input裏面的值。在這些函數中,有80%會包括一個this.setState() 的函數調用,或者若是是Redux的action回調(那樣的話,你不得再也不建立另外10個常量來匹配這10個input)。我猜,你必定想若是能靠腦補就自動生成這些關聯代碼就行了,可是我目前尚未發現哪一個ide能夠提供這樣的插件。

    爲何咱們不得不歸類這麼多?由於雙向綁定被一些大企業的大佬們認爲是很危險的。我也認可使用雙向綁定的數據流進行編碼,有可能可讀性不是那麼好,可是這些擔憂大部分都是由於Angular 1的雙向綁定帶來的負面影響,並且這可能也不是雙向綁定最大的值得擔心的地方。

    如今讓我爲你展現一個快速編輯器組件,這個組件是我最近用Vue.js爲咱們的Drupal網站構建的。

    我沒有貼出個人源碼的緣由顯而易見,可是用Vue編碼的過程是有趣的,而且代碼的可讀性很強。

    如今,我很確信,若是要我使用React完成上圖中的操做,就須要爲每個input建立一個單獨的函數,來達到控制一個掛件的目的,這樣作,並不會讓我感到快樂。

    Redux 聽上去就像是冗餘的同義詞,如今也很容易的找到一些開發者,他們的職責是將React轉型成Angular。這麼作也只是由於想要讓數據實現雙向綁定。個人第一個要點是「1 關於純淨」。彷佛不少聰明的人會讓他們的代碼庫變得比他們的工做更有價值(我猜,當你的工做沒有截止日期的時候,必定很爽)。

    過多的依賴

    React須要被babel編譯,若是沒有一連串的npm包,你的react項目將會步履維艱,因此先用es5進行開發。最簡單的應用開發也會須要基於一些官方的React依賴包,這些包在node_modules裏面,大約有75MB。

    這不是在批判,這些依賴這麼多,更多緣由是因爲js自己的緣由,而不是React的緣由。可是這些綜合因素加起來,使得使用React開發變得很累。

    Angular 1:太自由反而不是好事

    ng1曾經也是一個偉大的框架它與React徹底相反,它的代碼可閱讀性更好,它容許你快速上手,在剛剛開始的1K行代碼中,你的確感覺到了許多的樂趣,以後它就會讓你一直寫出糟糕的代碼。你極可能在大量的指令,scope和雙向數據流中迷失方向,它們貫穿於你全部的應用中難以維護。由於是難以維護的,因此讓大家新加入的開發者去維護舊系統,更是讓人拒絕的。

    爲何會這樣呢?

    ng1創造於2009年,那時候的前端應用都還很簡單,沒有人想到以後會有這麼多狀態管理的問題。你不該該去責備他們,他們只是想用一些新理念超越Backbone,而且寫更少的代碼。

    Angular 2

    爲了構造一個hello world的應用,而後找到項目的入口文件,你須要使用Typescript而且編譯它們才能夠開始工做。這實際上仍是要在我真正開始工做以前,所作的一些規範。依我看來,開發ng2的人嘗試去構建一個更優雅的框架戰勝React,而不是嘗試去構建一個能解決大多數用戶問題的框架。可能我這個想法是錯的,我對於ng2也尚未太多的經驗,由於咱們僅僅是用它爲咱們的貨倉作了一套用戶的計算器系統,用來測試它的框架性能。這有篇寫的很好的對比其餘框架的文章,ng2的確是很棒的框架,這篇文章裏也與Vue進行了許多的對比。

    Vue.js

    簡單的說,Vue.js 就是我等待已久的框架(我將會討論Vue2,一個比初版改進了不少的框架,而且也在最近發佈了穩定的版本)。對我來講,Vue的優雅和簡潔可以讓我更加專一於業務代碼。Vue能夠說是2007年的jQuery以後,又一個給JS世界帶了巨大改變的框架了。

    若是你想看看Vue的人氣,你會發現不只僅只有我是看好Vue的:www.timqian.com/star-histor…

    Vue.js能成爲2016年裏高速發展的JS架構之一,我認爲它的發展不只僅是靠粉絲的支持,更是由於一些權威組織的學術支持和確定。

    Laravel也把Vue.js添加到它的核心思想中去,這是一個值得關注的事情。

    Vue.js的特色

    Vue.js在代碼的可讀性、可維護性和趣味性的方面的處理可謂是會心一擊。若是你看過Vue的文檔指南,你會立刻發現,這個框架將比React和Angular 1 帶來更好的編程體驗。

    對比React,React是一個以組件爲基礎的框架,每一個組件實例有本身的方法、屬性、順着組件層級的單向數據流、函數調用、虛擬dom、和狀態管理。

    對比Angular 1,Angular 1 更像是一個有着優秀語法的模板,而且有你必定會須要的雙向數據綁定(在單個組件內)。

    Vue.js是一個很容易起步的框架,這在咱們的團隊中已經獲得了印證。它不須要強制的基於任何編譯環境,因此它能很容易地和你的歷史遺留代碼結合,而且能立刻用Vue的代碼改善歷史用jQuery編碼時的問題。

    快速獲得正確的結果

    不管是在html,仍是在js中使用框架,Vue.js都是一個很容上手的框架。它讓你在操做一個複雜的模板的時候,你能夠專一你的業務。而且即便這個模板很是大,也能有很強的可讀性。在這個時候,你就能更方便地根據你的業務邏輯處理好的你的代碼邏輯。若是你想重構模板而且拆分它們成更小的組件,你也能夠從剛開始的大模板中更清晰地看到整個應用的關聯關係。

    從個人開發經驗來看,這種開發模式與我用React開發的時候有着巨大的差異:我能從中節約好多時間。在用React的時候,你不得不在第一次編碼的時候就把你的組件拆分紅一個個的小組件,或者你能夠直接把你原來的代碼直接刪了。在使用React的過程當中,當你編程編到一半,不得不由於應用邏輯改變而去改變你的數據流的時候,你極可能會由於沒法清晰的看到完整數據流,致使了你花費不少時間去一次次地修正你的屬性和狀態,而且還要一次次重構你那些超級小的組件(可能以後根本用不到的小組件)。

    在Vue.js中操做表單也是垂手可得的。雙向綁定的數據流是Vue的一大亮點。即便是在複雜的場景下也不會帶來任何問題,雖然第一眼看到watcher可能會讓人想起Angular 1。當你拆分你的組件時,你老是能經過回調來單向傳輸須要改變的數據。

    若是你想要使用一些預處理的工具,好比PostCSS、ES6,能夠點這裏。在Vue2裏面,寫一個公共組件已經成爲拓展Vue的默認方式了。順便值得一提的是,在組件內編寫css,是一種看起來很棒的體驗,它可以減小傳統css的命名的層級問題,就像BEM同樣。

    Vue.js有簡單的、高效的狀態管理機制,好比用data()和props(),他們能在實際場景的使用過程當中發揮很大的做用。而且可以經過Vuex更好的分離狀態管理,幫助咱們更有效的管理狀態(Vuex在我看來是一個和React中的Mobx差很少的狀態管理工具,一款把狀態操做和狀態分離的管理工具)。

    VueJS的一些問題

    一、最大的問題就是:對運行過程的模板錯誤並無提示。這一點和Angular 1 很像。Vue.js會在你的開發過程當中提供不少有用的警告,好比,當你錯誤的修改props或錯誤定義data()的時候,會有警告提示。但模板運行過程當中的錯誤是Vue的一個弱點,特別是屢次的堆棧處理並無什麼用,這和Vue的內部方法有關。

    二、Vue.js 2 還很新,它尚未穩定的組件社區,現有的不少組件也都是基於Vue.js 1 構建的。而且對剛入門的人來講,可能很難從github的一些組件倉庫裏看出,這個庫使用的是Vue的哪一個版本。但其實,這個問題也好解決,由於你幾乎能夠不用使用任何的附加庫,就可以完成一個複雜的Vue的項目。你可能只會須要一些ajax請求的庫。若是你並不關心同構應用的話,vue-resource是一個不錯的選擇,不然請選擇axios。而且vue-router也是一個常常被使用的庫,一個可以提供路由的很棒的庫。

    三、中文文檔也在不少社區上都能找到,這很正常,由於Vue.js在中國也很流行(做者也可以說中文)。

    四、是一我的寫了一個項目嗎?這實際上算不上是一個問題,可是也有人會在乎。尤小右是一個曾在Google和Meteor工做的男人,是他創造了Vue。Laravel曾經也是隻有一我的在寫的項目,但如今也已經取得了巨大的成就,因此你無從得知一我的寫出來的項目有多強大。

    使用Vue.js開發Drupal

    免責聲明:咱們沒有打算很快的在Qwintry中使用Drupal 8,當咱們切換到更快更便捷的PHP和NODE框架的時候,咱們的歷史遺留代碼仍然使用Drupal 7。

    由於咱們是用Drupal 7 構建咱們的歷史系統(qwintry.com),所以對新框架的測試對咱們來講很重要。我一點也不爲咱們冗餘的歷史代碼感到自豪,可是它確實穩定運行着,併爲咱們盈利。因此咱們維護它,改善它,併爲它增長功能。在這裏我羅列了一些我已經用Vue + Drupal構建好的功能:

    爲複雜的訂單業務設計的系統。包括給用戶生成訂單、對購買項的快速編輯。包括在加載的時候加載一些基本的JSON數據和保存一些數據結點。這些都沒什麼特別的,只是一些簡單的數據回調。

    兩套REST的系統。咱們的用戶不用在不一樣的網站上重複登陸,咱們爲特殊用戶快速檢查身份信息。這些操做都是基於咱們的用戶管理系統。

    我知道有不少後端開發者仍然停留在2010年的時代,而且也知道Drupal 7 的核心就是Ajax請求系統。

    我可以想象,嘗試利用多步Ajax請求來重構核心功能,是多麼的複雜。以後想要去維護這些代碼更是難上加難。沒錯,就是Drupal裏面的ctools_wizard_multistep_form() 這個函數,你能夠看看它的ajax是如何操做的

    而且,這些Drupal開發者都在抓緊時間學習不少流行的UI框架,可是他們可能比較懼怕學習流行的JS框架。我一年前也是這樣。如今讓我來告訴你,你很難找到更好的方式來改善你的接口,可是如今使用了Vue.js就不同了。你能夠根據drupal_add_js把你的請求地址加入到模板中,而後就能夠去放鬆了。你必定會震驚,客戶端可以在你設置的鉤子的回調裏,這麼容易的就拿到了純淨的JSON,表單也是同樣的,這麼方便的操做都是由於使用了Vue。

    配合Yii2使用Vue.js

    一個有趣的事,Yii也是一箇中國boy作的 -- 薛強。因此你可能會發現Yii + Vue這樣的技術棧的發音並非很難,由於這也是一箇中國人創造的技術 :)

    在咱們新版本的網站Qwintry.com(還沒上線)的項目裏,咱們選擇使用Yii2,我相信它是PHP框架裏最好最快之一。雖然它不像Laravel那樣流行,畢竟Laravel如今已經席捲了PHP世界了,可是咱們在使用Yii2開發的過程當中仍然很開心(雖然咱們也時不時的去看看Laravel的發展,畢竟這個框架仍是至關不錯的)。

    咱們在逐漸減小使用Yii2來生成html 模板,後臺把注意力集中在REST上,生成JSON給咱們用Vue構建的客戶端使用。咱們的動態記錄模型幾乎都是先肯定好API,而後再構造數據。

    相應的,咱們也有很規範接口設計,這就是咱們爲何要花費大量的時間去構建好咱們的接口文檔,即便這些文檔只是咱們內部使用。

    咱們的後端是用PHP7和最新的MySQL進行開發的,使用Yii2返回數據的響應時間和使用Node返回數據的響應時間沒什麼差異(我是說15-20ms左右的差異)。因此Yii2是符合咱們要求的。咱們能夠想象用戶使用咱們的Drupal項目的時候,速度會比原來提高10-20倍。同時,它也支持全部老版本的PHP庫,可以讓咱們很方便地利用人工去更好的維護咱們的代碼庫。

    因此,Yii2 + Vue.js的開發搭配可以發揮出很大效用,而且可以讓你的工做變得更愉悅。

    咱們也在咱們的不少其餘項目上使用Vue.js。

    結論

    這三個月以來咱們天天都在各類項目中寫着Vue.js,讓咱們受益不淺。三個月不用寫後端代碼,卻全是JS的世界。讓咱們對這個世界拭目以待 :)

    我但願在將來的16-24個月內,Vue能成爲一個不可替代的JS框架。若是小右能讓這個框架向着正確的方向發展,Vue至少能夠成爲一些前、後端團隊核心框架。我認爲,即便到了2017年,React依然還會是JS世界的主要框架,特別是,若是RN可以更好地管理本身,並保持它以往的節奏去改善本身的話。

    原文地址: Why we chose Vue.js over React


    本文對你有幫助?歡迎掃碼加入前端學習小組微信羣:

    相關文章
    相關標籤/搜索