面試官:談談 Vue 和 React 的區別?
首先找到 Vue 和 React 的共性,它們被用於解決什麼問題, 然後再挖掘各自獨特的個性、設計原理以及未來的趨勢等。
vue 和 react 區別
共同點
Vue 和 React 存在着很多的共同點:
-
數據驅動視圖
-
組件化
-
都使用
Virtual DOM
1. 數據驅動視圖
在 jquery 時代,我們需要頻繁的操作 DOM 來實現頁面效果與交互;而 Vue 和 React 解決了這一痛點,採用數據驅動視圖方式,隱藏操作 DOM 的頻繁操作。所以我們在開發時,只需要關注數據變化即可,但是二者實現方式不盡相同。
2. 組件化
React 與 Vue 都遵循組件化思想,它們把注意力放在 UI 層,將頁面分成一些細塊,這些塊就是組件,組件之間的組合嵌套就形成最後的網頁界面。
所以在開發時都有相同的套路,比如都有父子組件傳遞, 都有數據狀態管理、前端路由、插槽等。
3. Virtual DOM
Vue 與 React 都使用了 Virtual DOM + Diff算法
, 不管是 Vue 的 Template 模板 +options api
寫法, 還是 React 的 Class 或者 Function 寫法, 最後都是生成render
函數,而render
函數執行返回VNode
(虛擬 DOM 的數據結構,本質上是棵樹)。
當每一次 UI 更新時,總會根據 render 重新生成最新的 VNode,然後跟以前緩存起來老的 VNode 進行比對,再使用 Diff 算法(框架核心)去真正更新真實 DOM(虛擬 DOM 是 JS 對象結構,同樣在 JS 引擎中,而真實 DOM 在瀏覽器渲染引擎中,所以操作虛擬 DOM 比操作真實 DOM 開銷要小的多)
Vue 和 React 通用流程:
圖片. png
不同點
Vue 和 React 兩者雖然都是用於構建用戶界面的框架,但是也有很大的差異,首先二者核心的思想就不同。
1. 核心思想不同
Vue 早期開發就尤雨溪大佬,所以定位就是儘可能的降低前端開發的門檻,讓更多的人能夠更快地上手開發。這就有了 vue 的主要特點:靈活易用的漸進式框架,進行數據攔截/代理,它對偵測數據的變化更敏感、更精確
。
React 從一開始的定位就是提出 UI 開發的新思路。背靠大公司 Facebook 的 React,從開始起就不缺關注和用戶,而且 React 想要做的是用更好的方式去顛覆前端開發方式。所以React推崇函數式編程(純組件),數據不可變以及單向數據流
, 當然需要雙向的地方也可以手動實現, 比如藉助onChange
和setState
來實現。
由於兩者核心思想的不同,所以導致 Vue 和 React 在後續設計產生了許多的差異。
2. 組件寫法差異
React 推薦的做法是JSX + inline style
, 也就是把 HTML 和 CSS 全都寫進 JavaScript 中, 即 all in js
; Vue 推薦的做法是 template 的單文件組件格式 (簡單易懂,從傳統前端轉過來易於理解
), 即 html,css,JS 寫在同一個文件 (vue 也支持 JSX 寫法)
這個差異一定程度上也是由於二者核心思想不同而導致的。
3. diff 算法不同
傳統 Diff 算法是循環遞歸每一個節點:
傳統 diff
如上圖所示,從左側 a 節點依次進行對比:a->d
、a->e
、a->b
、a->a
、a->c
, 剩下的其他節點也是與右側樹每個節點進行對比。
將兩顆樹中所有的節點一一對比需要
O(n²)
的複雜度,在對比過程中發現舊節點在新的樹中未找到,那麼就需要把舊節點刪除,刪除一棵樹的一個節點 (找到一個合適的節點放到被刪除的位置) 的時間複雜度爲O(n)
, 同理添加新節點的複雜度也是O(n)
, 合起來 diff 兩個樹的複雜度就是O(n³)
傳統 Diff 算法複雜度太高, vue2.x 加入了 Virtual Dom
和 react 擁有相同的 diff 優化原則(將算法複雜度降爲O(n)
)。
兩者流程思路上是類似的:
-
不同的組件產生不同的 DOM 結構。當 type 不相同時,對應 DOM 操作就是直接銷燬老的 DOM,創建新的 DOM。
-
同一層次的一組子節點,可以通過唯一的 key 區分。
網絡上看到一張圖挺形象的圖:
但是在源碼實現上又完全不同:
React 的 Diff 算法核心實現
圖片. png
-
react 首先對新集合進行遍歷,
for( name in nextChildren)
。 -
通過唯一 key 來判斷老集合中是否存在相同的節點。如果沒有的話創建
-
如果有的話,
if (preChild === nextChild )
-
會將節點在新集合中的位置和在老集合中 lastIndex 進行比較
-
如果
if (child._mountIndex < lastIndex)
進行移動操作,否則不進行移動操作。
- 如果遍歷的過程中,發現在新集合中沒有,但在老集合中有的節點,會進行刪除操作
Vue 的 Diff 算法核心實現
updateChildren
是 vue diff 的核心, 過程可以概括爲:
-
舊children
和新children
各有兩個頭尾的變量StartIdx
和EndIdx
,它們的 2 個變量相互比較,一共有 4 種比較方式。 -
如果 4 種比較都沒匹配,如果設置了 key,就會用 key 進行比較,在比較的過程中,變量會往中間靠,一旦
StartIdx>EndIdx
表明舊children
和新children
至少有一個已經遍歷完了,就會結束比較。
可以用下圖來描述在一次比較過程中四個步驟:
圖片. png
Vue2 的核心 Diff 算法採用了雙端比較的算法,同時從新舊 children 的兩端開始進行比較,藉助 key 值找到可複用的節點,再進行相關操作。相比 React 的 Diff 算法,同樣情況下可以減少移動節點次數,減少不必要的性能損耗,更加的優雅。
4. 響應式原理不同
Vue
-
Vue 依賴收集,自動優化,數據可變。
-
Vue 遞歸監聽 data 的所有屬性, 直接修改。
-
當數據改變時,自動找到引用組件重新渲染。
React
React 基於狀態機,手動優化,數據不可變,需要setState
驅動新的 state 替換老的 state。當數據改變時,以組件爲根目錄,默認全部重新渲染, 所以 React 中會需要 shouldComponentUpdate
這個生命週期函數方法來進行控制
5. 其他不同點
除了上面的四個點外,細數還有很多不同點的, 比如 api 的差異也挺大的,Vue 爲了更加簡單易用,引入了指令、filter 等概念以及大量的 option API, 比如 watch
、computed
等都是非常好用的。
而 React 的 API 比較少, 如果你的 JavaScript 基礎比較好,上手也是比較容易的
當然如果你看過二者的源碼,也可以說說二者源碼的不同點。這裏拋出它們的源碼編譯過程圖,方便你更好的閱讀源碼。
Vue 源碼編譯過程圖:
React 源碼編譯過程圖:
React 源碼編譯過程圖
以上就是關於Vue和React的區別
講解, 當面試官問到這個問題時,重點在於分析思路, 抓住要點去擴展。最後我們還可以談談未來發展趨勢,其實隨着 Vue3 的更新,和 React 在使用上相似度越來越高, 其實對於開發者來說挺好的, 上手一個框架後再學另一個,學習成本就會有所降低。
面試題:你瞭解瀏覽器的事件循環嗎?
面試題:實際開發中都做過哪些性能優化?
本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源:https://mp.weixin.qq.com/s/oiNmF8knHfnvbmZfYTv_ZQ