Vue 和 React 有什么不同?
大家好,我是前端西瓜哥。今天的文章簡單探討一下 Vue 和 React 的不同。
本人 Vue2 和 React 都用過,但不熟悉 Vue3,沒用它做過項目。
其實我對這兩大框架也沒有認真鉆研過它們的細節(jié),也就是工作上用它們寫一些簡單業(yè)務,或偶爾看看相關的博客文章,但還是有一些淺顯的認識的,寫下來記錄一下。
Vue 和 React 都是用于構建 UI 界面的流行框架。
它們的哲學也有很多相似的地方,我們可以認為這些特性是流行前端框架的一個趨勢。它們是。
- 組件化。將結構、樣式、腳本進行耦合,讓界面一部分區(qū)域能夠獨立出來,并可以提供復用。
- 聲明式。摒棄了 JQuery 那種手動操作 DOM 的刀耕火種的方式,而是通過聲明一些狀態(tài),當狀態(tài)改變時自動更新 DOM
- 虛擬 DOM。虛擬 DOM 是對真實 DOM 的模擬,但比真實 DOM 輕量,用作新舊樹對比計算出補丁。此外虛擬 DOM 作為真實 DOM 的抽象,讓跨平臺成為可能,不同平臺實現(xiàn)自己的虛擬 DOM 即可。
- Hook。React 帶來了 Hook 概念,用于管理狀態(tài),并成為了潮流。
用法區(qū)別
不管如何,Vue 和 React 是兩個不同的框架,所以在用法上是有很多不同的。
列一些用法上的區(qū)別。
組件 props
Vue 組件,表現(xiàn)上更接近原生 DOM 節(jié)點,你在上面加原生的 class、id、style 等 props,是會被添加到 Vue 組件的根節(jié)點上的,添加 style 和 class 會比較方便。
而 React 組件的所有 Props 你都需要自己處理,像是 style 和 className 這些 props 是要自己手動處理的。
function Component (props) {
return (
<div style={props.style} className={classNames('app', props.className)}>
// ...
</div>
)
}
渲染
Vue 的渲染是基于模板(Temple),寫起來更像是 HTML,對新手比較友好。
React 則是用 JS 通過嵌套的 React.createElement 來描述 DOM。因為用 React.createElement 比較繁瑣,React 推出了 JSX,對 JS 擴展了一些語法,能夠使用接近 HTML 的寫法來表示 React.createElement。
JSX 要比 Temple 要靈活一些,更方便在里面加各種邏輯,調用各種函數(shù)生成一些 ReactElement,插入到 JSX 中。
Temple 沒這么靈活,本質是字符串。你需要用到一些指令去完成一些邏輯,比如 v-if、v-for,但更方便做性能的優(yōu)化。Vue 進行生產環(huán)境打包時,會對 Temple 預編譯,實際運行時不會真的對著 Temple 進行運行時編譯。
新手友好程度
Vue 比 React 對新手更友好。
首先是文檔。文檔是開源框架能否流行,一個重要的指標。
在中文文檔上我認為 Vue 寫得比 React 要好。
當然這也是我的主觀的感受,我想可能因為 Vue 的作者是國人的原因,文檔的內容更符合國人的習慣,用的短句比較多(我也不太清楚中文翻譯是否 Vue 作者進行大量參與)。下面是 Vue 文檔的一部分:
這和我們嵌套 HTML 元素的方式類似,Vue 實現(xiàn)了自己的組件模型,使我們可以在每個組件內封裝自定義內容與邏輯。Vue 同樣也能很好地配合原生 Web Component。如果你想知道 Vue 組件與原生 Web Components 之間的關系,可以閱讀此章節(jié)
React 的作者則是國外公司,長難句為主,中文一股讓人煩躁的翻譯腔。比如這個:
React 并沒有采用將標記與邏輯分離到不同文件這種人為的分離方式,而是通過將二者共同存放在稱之為“組件”的松散耦合單元之中,來實現(xiàn)關注點分離。我們將在后面章節(jié)中深入學習組件。如果你還沒有適應在 JS 中使用標記語言,這個會議討論應該可以說服你。
還得怪我英語不太好。當然還有其他的文章質量、章節(jié)組織相關的這些,都比較主觀。
然后就是 Vue 更接近原生寫法。
React 引入了很多優(yōu)秀的東西,但對新手來說是學習成本。比如高階組件、JSX、
React 技術選型更豐富。
如果是 Vue,那 Vue 官方自己已經提供了周邊的套件了。CSS 方案直接用 CSS-Scoped,狀態(tài)庫用 Vuex 或 Pina?;緵]什么社區(qū)的第三方輪子,就算有也是使用量不高。
對 React 團隊來說,他們將周邊庫的開發(fā)交給了社區(qū),所以你能收獲各種各樣不同的輪子,然后在上面糾結半天。CSS 方案,可以用 CSS-Module、styled-components、Radium 等。狀態(tài)庫,你可以用 Redux、Mobx、Zustand、Recoiler、Dva 等。
對老鳥來說,技術選型花點時間還是能選擇,但對新手來說,讓他們去對比各種輪子,就帶來了更多的成本。
在你經歷了不少項目后,你會發(fā)現(xiàn) Vue 的技術選型比較穩(wěn)定,React 的技術選型則是五花八門。
流行程度
React 要比 Vue 流行。
React 是大公司 Facebook(現(xiàn)在改名叫 Meta,還是不太習慣)開源的框架,背后是有團隊進行維護的,各個都是大佬。
Vue 更多是個人項目,開始是尤雨溪一個人在維護,后來雖然也有了團隊,但其實開發(fā)工作大部分都在尤雨溪身上,看下圖,第一名和第三名的 commit 數(shù)不是一個數(shù)量級的(第二名是機器人,忽略不計)
再看看 React 的貢獻者 commit 數(shù)據(jù):
一個項目的未來是受到項目的靈魂人物的影響的,不少項目因為作者的離開導致缺乏維護,推及大量未處理的 issue。
對于 Vue 來說,它的靈魂人物是尤雨溪。對 React 來說,更去中心化一些,靈魂人物更去中心化一些。
React 的社區(qū)方案會更多。
這也和 React 更加流行有關,且 React 團隊專注于打造 React 本身。
性能
Vue 的性能優(yōu)于 React。
Vue 的響應式可以做到只更新必要的組件,性能更優(yōu)。
Vue 的底層是響應式,它會劫持狀態(tài)的讀寫,進行細粒度的依賴收集。當狀態(tài)變化時,只有用到它的組件才會更新。
React 則是純正的單向數(shù)據(jù)流,數(shù)據(jù)從父組件流向子組件。當父組件更新時,子組件也會更新,即使這個子組件的狀態(tài)沒有變化。為了跳過這種無必要的渲染,我們需要額外使用 React.memo 做緩存,需要付出不小成本,一不小心還會整成負優(yōu)化。
React 其實也可以變成響應式,加一個狀態(tài)管理庫,通過發(fā)布訂閱模式觸發(fā)組件更新即可,但它不能拯救性能。
Vue 做了編譯優(yōu)化。
對于渲染模板方案,Vue 使用了Temple,React 使用了 JSX。
Vue 的 Template 可以做預編譯優(yōu)化。比如一些 DOM 元素是寫死的,解析 Template 時,就可以做標記,在第 n 個位置的元素是靜態(tài)的,就不需要在更新的時候重新構建對應節(jié)點,進行 diff 了。
<div>前端</div> // 這個寫死的,更新時不重新渲染這個
<div v-if="visible">{{ count }}</div>
<div>西瓜哥</div> // 這個也寫死
JSX 是完全動態(tài)的,我們不知道哪些元素是不變的,只能全部都再生成一遍然后。對于寫死的不變元素,對比其實做了無用功。
靈活與規(guī)范
Vue 更規(guī)范,React 更靈活。
Vue 的單文件組件(.vue 后綴的文件)指的是一個文件里,放入了 temple、script 和 style,來代表一個完整的組件。在這個文件里,你只能聲明一個組件,不能聲明多個。
但 React 可以在一個文件里聲明多個組件。你可以將樣式放到另一個文件,然后引入進來。你可以多個組件共用同一份樣式文件,你可以在組件內用 renderXx 來嵌套一個有相同上下文的組件。它很靈活,但也是雙刃劍,它會讓水平不足的同事肆意破壞一切。
React 太靈活,雖然可以天馬行空地用你更舒服的方式去實現(xiàn)需求,但它下限低。
Vue 有范式,你要按照標準辦事,項目代碼不會太過于崩壞,且因為依賴收集按需更新組件,性能優(yōu)秀,讓用 Vue 編寫的代碼有較高的下限,某種意義上確實適合中小公司。
其他
React 更傾向于函數(shù)式編程,提倡 immutable,即數(shù)據(jù)不可變,每次組件更新時,拿到的狀態(tài)都是全新的數(shù)據(jù)。React Hook 就是為了讓函數(shù)組件成為主流而誕生的。
結尾
React 和 Vue 之間黨派之爭總是爭端不斷,我覺得你喜歡哪個就用哪個,然后尊重其他人的選擇即可。