一、前言:我全都要
面對當(dāng)今前端界兩座大山一樣的主流框架,React 和 Vue,相信很多小伙伴都或多或少都產(chǎn)生過這樣疑問,而這樣的問題也往往很讓人頭疼和猶豫不決:
- 業(yè)務(wù)場景中是不是團(tuán)隊(duì)用什么我就用什么?
- 如果選擇了其中一個(gè)使用,那為什么不用另一個(gè)?
- 這兩個(gè)框架各有什么優(yōu)點(diǎn)和無法解決的問題?
- 最新版本的 Vue3 已經(jīng)出了一段時(shí)間了,我要不要做組內(nèi)第一個(gè)吃螃蟹的勇士?
- 我該依據(jù)什么樣的因素決定使用哪個(gè)技術(shù)棧?
以上問題如果想不明白,很容易產(chǎn)生一個(gè) “算了不想了真麻煩,還是隨大流好了,至少不會(huì)出錯(cuò)” 的答案,其實(shí)種種疑問都指向了一個(gè)終極問題,那就是關(guān)于技術(shù)棧的選型 。而技術(shù)棧選擇的合適與否,往往對項(xiàng)目后續(xù)的開發(fā)有著極大的影響,甚至關(guān)系到業(yè)務(wù)落地的效率和效果。僅僅掌握業(yè)務(wù)邏輯的開發(fā),已經(jīng)完全不能滿足個(gè)人發(fā)展了, 就好比一門武林絕學(xué),招式用的再熟,也需要心法輔佐,所以也就引出了本文的主題:
- 旨在幫助那些對技術(shù)棧選擇困難癥的同學(xué),并對 React 和 Vue 產(chǎn)生一定的認(rèn)知
- 同時(shí)也適合那些只了解單一技術(shù)棧的小伙伴,可以拓展一下對不同框架的理解
基于 Spring Boot + MyBatis Plus + Vue & Element 實(shí)現(xiàn)的后臺(tái)管理系統(tǒng) + 用戶小程序,支持 RBAC 動(dòng)態(tài)權(quán)限、多租戶、數(shù)據(jù)權(quán)限、工作流、三方登錄、支付、短信、商城等功能
二、正文:到底要啥
本文不會(huì)從正面回答上面列出的問題,技術(shù)棧的選擇往往要依據(jù)現(xiàn)實(shí)情況從多方面考慮,所以我也將從以下幾個(gè)方面分別闡述觀點(diǎn),各位讀者可以結(jié)合自身情況和以下觀點(diǎn),決定 React 和 Vue 到底要用哪一個(gè)。而其實(shí)關(guān)于技術(shù)選型,很容易代入自己的主觀意識(shí),“好和壞” 在同樣優(yōu)秀的框架面前更像是一種自我感受 ,但筆者會(huì)盡量從客觀的角度去闡述,如果過程中觀點(diǎn)出現(xiàn)沖突或有誤,歡迎與我交流、指正。
- 選型對象說明
- 團(tuán)隊(duì)的適用性
- 兼容性要求
- 使用層面對比
- 周邊配套
- 跨端處理
- 設(shè)計(jì)思路
- 性能對比
- 心智模型
- 社區(qū)生態(tài)
- 開源代碼許可協(xié)議
1. 選型對象說明
對比對象:React(hooks 版本)、Vue2、Vue3
關(guān)于對比對象的選擇:
- React 有函數(shù)式組件的和類組件兩種寫法,鑒于 class 寫法較老,且這種寫法不利于構(gòu)建工具的 Tree-shaking ,可能導(dǎo)致構(gòu)建產(chǎn)物體積增加,而函數(shù)式組件的 hooks 寫法更符合未來的潮流 , 所以類組件在此也不做詳細(xì)的介紹,只選取函數(shù)式組件寫法的 React 作為對比對象。
- Vue2 相較 Vue3 版本而言牢牢占據(jù)著大部分 Vue 開發(fā)者的視野,但是因?yàn)?Vue 官方已經(jīng)把 Vue3 作為默認(rèn)的版本,所以在此同時(shí)把 Vue2 和 Vue3 作為對比對象。
- 對比的內(nèi)容不會(huì)涉及到具體的某個(gè) API 的實(shí)現(xiàn),也不會(huì)講解大篇幅干澀的源碼,過于詳細(xì)的內(nèi)容不是本文的重點(diǎn),作為技術(shù)選型要從整體出發(fā)去考慮。
2. 團(tuán)隊(duì)的適用性
在這方面,其實(shí)選哪個(gè)框架取決于團(tuán)隊(duì)全體成員
- 歷史原因:如果你是以開發(fā)者的身份剛?cè)肼毜揭粋€(gè)新的環(huán)境,并且接手的是一個(gè)成熟的項(xiàng)目,處于正常迭代或者維護(hù)周期,那千萬不要想著顛覆團(tuán)隊(duì)已有技術(shù)棧,技術(shù)棧切換就相當(dāng)于重構(gòu) 。而這種重構(gòu)面臨的首要影響就是投入和產(chǎn)出不成正比,相信文章的讀者大多也都是撲在各個(gè)業(yè)務(wù)一線上,對業(yè)務(wù)方來說,采用什么樣的技術(shù)去實(shí)現(xiàn)他們并不關(guān)心,并且切換技術(shù)棧帶來的風(fēng)險(xiǎn)、開發(fā)人力和測試回歸的成本都難以評估,除非帶來巨大價(jià)值,否則這也是與我們合作的上下游都難以接受的。
- 團(tuán)隊(duì)習(xí)慣:如果你是項(xiàng)目負(fù)責(zé)人,在拋開對框架本身進(jìn)行對比的同時(shí),要考慮的是團(tuán)隊(duì)成員對技術(shù)棧的熟悉程度,在大多數(shù)人都對某一項(xiàng)技術(shù)棧熟悉、而對另一項(xiàng)技術(shù)了解不深的情況下,那更為熟悉的技術(shù)棧帶來的人效和產(chǎn)出質(zhì)量,顯然能幫助業(yè)務(wù)快速驗(yàn)證和試錯(cuò)。
注意 :不熟悉某項(xiàng)技術(shù),絕不能成為不使用這項(xiàng)技術(shù)的托詞,從個(gè)人提升的角度考慮,學(xué)習(xí)新的技術(shù)棧可以幫助我們擴(kuò)充思路和視野,如果要做的新項(xiàng)目 周期不緊張,也預(yù)留了充足的時(shí)間,那么新的技術(shù)顯然可以作為備選項(xiàng)之一。
3. 兼容性要求
- PC 端:React 和 Vue 均不支持 IE8,對于個(gè)別瀏覽器兼容模式使用 IE 內(nèi)核也可能是不支持的,具體要看使用的內(nèi)核版本(IE 瀏覽器簡直是前端界的噩夢),其他瀏覽器下可以放心大膽地使用了。
- H5 端:React 和 Vue 2.x 均能使用。
注意 :在移動(dòng)端對于想要嘗鮮 Vue 3.x 版本的同學(xué)來說要關(guān)注一下,Vue 3.x 依賴收集是使用 Proxy 這個(gè) API,而 Proxy 在 IOS 端最低支持 IOS10 版本,并且由于這個(gè) API 具備更底層的對象監(jiān)聽能力,導(dǎo)致 polyfill 無法完全兼容,已實(shí)現(xiàn)的 polyfill 都是基于 Object.defineProperty,并不能完整支持 Proxy 所有特性(比如數(shù)組長度的監(jiān)測),所以如果業(yè)務(wù)環(huán)境對 IOS9 有兼容需求的情況下,就不要嘗試了。
4. 使用層面對比
框架引入
- React 和 Vue 都是漸進(jìn)式框架,支持 script 標(biāo)簽直接使用,也支持在工程中通過模塊化方式引入使用。
Jsx VS Template
- React:采用的 Jsx 在寫法上更為靈活多變 ,屬于在 Js 中增加了 HTML 語法,組件的實(shí)現(xiàn)思路是 All in Js ,開發(fā)過程中擁有 Js 完整的生態(tài)。同時(shí)開發(fā)工具對 JSX 的支持相比于現(xiàn)有可用的其他 Vue 模板也比較先進(jìn) (比如,linting、類型檢查、編輯器的自動(dòng)完成)。
- Vue:整體思路是 Template 模板語法,跟 Jsx 相比,它是在 HTML 中增加了對部分 Js 語法的支持,在靈活度上不如 Jsx,本質(zhì)是模板語法無法窮舉所有 Js 能力,所以筆者認(rèn)為 Vue 內(nèi)部使用的 slot、directive 等,也恰恰是對模板語法不夠靈活所做出的一種補(bǔ)充,使模板語法也能完成跟 Jsx 同樣的事情。模板語法也有優(yōu)點(diǎn),它更接近原生 HTML,對于新手上手更友好 ,并且在 Vue3 中,它從模版層面進(jìn)行靜態(tài)分析,對靜態(tài)模版做標(biāo)記,從而提升 diff 的效率 。值得一提的是,與 React 一樣,Vue 在技術(shù)上也支持 render 函數(shù)和 Jsx,但只是不是默認(rèn)的而已。
那么你可能會(huì)有疑問,為什么 Template 不去適配所有的 Js 語法?這里舉一個(gè)例子:Taro 。
Taro1.x 和 Taro2.x 采用了窮舉所有 Jsx 語法的方式,去生成不同平臺(tái)的代碼,導(dǎo)致每次 Jsx 或 Js 語法有更新,這兩個(gè)版本的 Taro 編譯器都要同步去做適配,這是一種重編譯時(shí)的方案,對 Jsx 的支持其實(shí)非常痛苦,所以 Taro3 索性采取了重運(yùn)行時(shí)、輕編譯時(shí)的重構(gòu),以獲得編譯器對 Jsx 更有好的支持。并且還有另一個(gè)原因是,我們假如 Template 支持了所有 Js 能力,那么勢必又導(dǎo)致了 Template 語法變得復(fù)雜,也可能和原本統(tǒng)一的 Ecma 規(guī)范割裂(層出不窮的小程序就是一個(gè)典型的例子,相當(dāng)于規(guī)范之中又出規(guī)范,生態(tài)之外再造生態(tài) ),造成了學(xué)習(xí)成本增加和沉重的編譯器。
- 共性 也是有的,都是 DSL,對底層而言,雖然兩者采用了不一樣的方式實(shí)現(xiàn),但最終都會(huì)被編譯為渲染函數(shù) 去執(zhí)行。
- 下圖是 Jsx 語法示例:
- 下圖是 Template 語法示例:
SFC
- HTML:React 是 Jsx,Vue 是默認(rèn)的 Template,在這里不在贅述區(qū)別,同時(shí)需要指出的是,Vue3 相較 Vue2 而言,Template 下可以允許存在多個(gè)根節(jié)點(diǎn) ,可以減少一些不必要的 DOM 層級。
- JS:React 組件本身就是 JS 文件,形式采用函數(shù)組件和類組件,編程范式上更貼近面向?qū)ο?+ 官方推崇的函數(shù)式。Vue2 組件是 Options Api,通過一個(gè)個(gè)配置項(xiàng)去實(shí)現(xiàn)生命周期、狀態(tài)聲明和邏輯開發(fā)。Vue3 對于部分邏輯處理和 Vue2 有很大區(qū)別,setup 模式下,已經(jīng)和 React 越來越趨同 了,編程范式是面向過程 + 函數(shù)式,官方命名為 Composition Api,可以使同一個(gè)功能邏輯更加集中。
- CSS:React 的 CSS 使用方式是直接通過 Import 導(dǎo)入,Vue 文件中有專門處理樣式的 Style 標(biāo)簽,值得一提的是,Vue3 內(nèi)置狀態(tài)驅(qū)動(dòng)的動(dòng)態(tài) CSS,詳細(xì)可查看官方文檔 https://cn.vuejs.org/api/sfc-css-features.html。
- 其他思考:React 的函數(shù)式組件和 Vue3Composition Api,在 ESM 模塊規(guī)范下對 Tree-shaking 更友好 ,更容易減少構(gòu)建體積。
組件使用
- React 組件僅需引入即可使用。
- Vue 的組件引入后需要全局或局部注冊,且組件內(nèi)的 Props 的要顯式聲明。
邏輯復(fù)用
- React 的復(fù)用主要體現(xiàn)在高階組件、render props 以及 hooks,但是也有他們對應(yīng)的不足。高階組件層級過深時(shí)容易帶來 props 的命名沖突、來源不明確的問題,并且額外的組件實(shí)例會(huì)有更多的內(nèi)存消耗。hooks 的引入,使 React 的邏輯抽離更容易,完全修復(fù)了命名沖突,來源準(zhǔn)確,且無額外開銷,可以貫徹函數(shù)式編程的理念。但是與此同時(shí),因?yàn)?hooks 中可能保留著組件狀態(tài),也意味著每次 React 的更新,如果不進(jìn)行手動(dòng)優(yōu)化,不論前后數(shù)據(jù)是否有變化,每個(gè) hook 都會(huì)重新執(zhí)行,這也是底層架構(gòu)上額外帶來的問題。
- Vue 的組件復(fù)用主要是是用 Mixin、Extend、插槽和 Vue3 的 Function API。Mixin:它和 React 的高階組件帶來的問題十分類似,響應(yīng)式數(shù)據(jù)命名沖突,以及邏輯來源不明確。插槽:主要功能點(diǎn)是組件復(fù)用,它解決了數(shù)據(jù)命名沖突的問題,同時(shí)數(shù)據(jù)來源準(zhǔn)確,但是也存在著額外組件實(shí)例帶來的內(nèi)存消耗 Function API:目前看來是較為優(yōu)秀的一種邏輯復(fù)用方式,沒有以上列出的所有問題,雖然和 React 的 hooks 十分相像,但是本質(zhì)不同 ,Vue 可以追蹤到數(shù)據(jù)變化,也僅在組件實(shí)例化時(shí)執(zhí)行一次。
樣式隔離方案
- React:CSS moduleCSS in JSBEM 命名規(guī)范
- Vue:官方支持 Style scopedBEM 命名規(guī)范
TS 支持
- React 本身就是 Js 和 Jsx,并且 TS 專門開了后門給做了支持(Jsx 其實(shí)一開始沒有類型支持,Tsx 的開發(fā)體驗(yàn)完全來自于 TS 專門針對 Jsx 制定的一整套推導(dǎo)機(jī)制),所以 Tsx 的類型支持也很完善 。
- Vue2.x 來自尤雨溪本人的回答是 “因?yàn)楫?dāng)初 API 的設(shè)計(jì)根本就沒有考慮類型系統(tǒng)”,2.x 跟 TS 的整合需要借助 vue-class-component 使用類組件進(jìn)行開發(fā),所以目前 2.x 版本的 Vue 對 TS 的支持度較 React 仍有差距,但是最近隨著 Vue2.7 的發(fā)布,可以使 Vue2.x 用上大部分 Vue3 的寫法,也使 Vue2.x 就具備了兼容 TS 的能力。
- Vue3,根據(jù)來自官方的建議,IDE 支持需用
審核編輯 :李倩
-
函數(shù)
+關(guān)注
關(guān)注
3文章
4345瀏覽量
62884 -
編輯器
+關(guān)注
關(guān)注
1文章
806瀏覽量
31258 -
vue
+關(guān)注
關(guān)注
0文章
58瀏覽量
7868
原文標(biāo)題:關(guān)于 “ React 和 Vue 該用哪個(gè)” 我真的栓 Q
文章出處:【微信號(hào):芋道源碼,微信公眾號(hào):芋道源碼】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。
發(fā)布評論請先 登錄
相關(guān)推薦
評論