You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
React 早期的口號是 Rethinking Best Practices。開宗明義地表示要用更好的方式去顛覆前端開發(在當時 jQuery 稱霸的時空背景下,現在看來確實完美顛覆了)。而在 React 中推崇函式編程(FP),其中包含數據不可變及單向資訊流等,在 Pure Function 的原則下,最大優點當然就是所謂的穩定性(沒有 side effect)及可測試/維護性(同樣的 input,必得到同樣的 output),而這也是為什麼 React 更適合大型、複雜應用的原因。
Vue & React 初開發比較與心得
📌 前言
既先前以 React 開發個人專案後,最近因為新工作需要使用 Vue ,所以轉而學習 Vue 開發,在這篇文章中會記錄我所感受與理解的 React 與 Vue 之間的差別。
📌 Vue 與 React 的共通點
其實上述幾點列出來,也是最近的學習感受,本質來說兩個框架幾乎是一樣的,只是差別在於兩個框架使用的設計思考。
📌 Vue 與 React 核心思想的不同
Vue 主打靈活易用的漸進式框架,也就是希望降低前端開發的門檻,因此很多人說 Vue 是目前三大框架中學習曲線最平緩的。而 Vue 的作者尤雨溪也曾如此回答:
Vue 原先的定位是盡可能降低前端開發的門檻,也因此可以從這個出發點理解為什麼 Vue 推崇所謂的
漸進式開發體驗
,對於一個初學前端開發的開發者而言,數據可變動、雙向綁定,每個組件都包含 html(template)、javascript、css 等,其實與既有的所謂經典web開發方式
所差無幾,也就相對而言較好理解與學習。這個核心價值的開展也或許可以歸結到尤雨溪本身是獨立開發者。React 早期的口號是
Rethinking Best Practices
。開宗明義地表示要用更好的方式去顛覆前端開發(在當時 jQuery 稱霸的時空背景下,現在看來確實完美顛覆了)。而在 React 中推崇函式編程(FP),其中包含數據不可變及單向資訊流等,在 Pure Function 的原則下,最大優點當然就是所謂的穩定性(沒有 side effect)及可測試/維護性(同樣的 input,必得到同樣的 output),而這也是為什麼 React 更適合大型、複雜應用的原因。在寫 Vue 時,會有 template、css、script 三個區塊組合,就像我們最開始在學習網頁開發時的 html、css、js 一樣。在 Vue 的官方文件中,也提到如此的設計思想是為了擁抱經典的 Web 開發技術。
Vue Component
相較 Vue 的經典,在 React 中,一切都是 JavaScript 為基底,就連 HTML 都以 JSX 來表達(HTML in JS),尤其搭配上 styled-components 時,基本上就感覺自己從來沒離開過 JavaScript 。
React Component
📌 狀態數據綁定的不同
Vue 雙向綁定 v.s React 單向綁定
或許這也可以說是兩者間最大的區別,Vue 提供反應式的數據,也就是當我們使用 v-model 將數據連動時,只要數據有所改動,介面就會自動更新,而在 React 中,我們則需要透過
onChange
或setState
方法來完成這件事。Vue 的作者尤雨溪將這兩者說明為Push-based
和Pull-based
。Push-based:Vue
改動數據後,數據本身會把這個改動推送出去,告知渲染系統進行畫面渲染。
Pull-based:React
我們需要額外主動去通知系統「你該進行渲染」,這時系統才會幫我們渲染畫面。
📌 監聽資料變化與渲染過程的不同
Vue
React
在 React 當某個組件的狀態發生變化的時候,會以該組件為根,重新渲染整個子組件,因此在寫 React 時,我們常會思考是不是會造成不必要的子組件渲染,因此就需要在所有可能的地方使用PureComponent,或是手動實現 shouldComponentUpdate 方法,但如此一來,我們也就必須保證該組件的整個子組件渲染輸出的影響都是由該組件的 props 所決定,不然就可能導致例外且難以察覺的渲染結果不一致,導致在組件優化的考量上,會耗費比較多心力。
但在 Vue 中,因為組件的依賴引用在渲染過程中是
自動追蹤
,所以系統精確知道哪些組件需要被重新渲染,我們可以簡單理解為在 Vue 中的每個組件都自動獲得 shouldComponentUpdate ,因此在 Vue 開發而言,這個特點讓開發者相較不需要考量這一類的效能優化問題,而能更加專注於開發工作。更清楚地說 Vue 之所以可以更快地計算出 Virtual DOM 的差異,是因為它在渲染過程中,會追蹤每一個元件的依賴關係(透過 getter/setter 等),不需要重新渲染整個元件樹,而 React 則是透過引用比較的方式(diff),因此如果開發不注意可能會導致大量且不必要的 VDOM 重新渲染,談到這裡可能會好奇,怎麼 React 不跟著監聽資料就好?
這就要回歸到最源頭的兩個框架設計理念的區別,Vue 資料的「可變」,與 React 資料的「不可變」,而這兩者也其實沒有真實所謂的優劣之分,Vue 在這點上可以說是開發更簡單,但 React 則是在建構大型應用的時候,能更好的維護。
📌 生命週期 hook
承上,Vue 中的組件也與 React 一樣,有所謂類似生命週期的方法,例如當組件就緒,掛載到頁面之前 (created),掛載到頁面時(mounted)、狀態更新時(updated)、組件撤銷時(unmounted)等 hook,而兩者最大的差別在於先前說的,Vue 本身是具有反應系統的,也就是已經預設了 shouldComponentUpdate ,所以在 Vue 裡當然就不需要它。
Vue Lifecycle
React Lifecycle
📌 diff 的算法不同
Vue 與 React 在實踐 Virtual Dom 的方法是相當類似的,都是基於以下兩點,將傳統 Diff 算法從 O(n³) 降為 O(n)。
React 的 Diff 算法核心實現
Vue 的 Diff 算法核心實現
updateChildren 是 vue diff 的核心,過程可以概括爲:
舊 children 和新 children 各有兩個頭尾的變量 StartIdx 和 EndIdx,它們的 2 個變量相互比較,一共有 4 種比較方式。
如果 4 種比較都沒匹配如果設置了 key,就會用 key 進行比較,在比較的過程中,變量會往中間靠,一旦StartIdx > EndIdx表明舊 children 和新 children 至少有一個已經遍歷完了,就會結束比較。
Vue 是基於 snabbdom 庫,採用雙端比較的 diff 算法,同時從新舊 children 的兩端開始進行比較,藉助 key 值找到可複用的節點,再進行相關操作。也就是說Vue Diff是採用
邊比較、邊更新
,而React則是使用 diff 對列保存需要更新那些 DOM ,算出 patch 樹後,在統一操作批量更新 DOM
,兩相比較下, Vue 可以減少移動節點次數,減少不必要的性能損耗,更加的優雅。📌 數據流向與傳遞不同 Event v.s Callback
Vue
React
Vue 與 React 都有方式可以輾轉達到子層項父層傳遞訊息,但 Vue 傾向於自定義事件(custom event)傳遞,而 React 則是使用回調函式。
📌事件機制的不同
Vue
React
原生事件經過包裝,所有事件會先冒泡到頂層 document 監聽後,才合成事件向下傳遞,因此可以跨端使用事件機制,而不是經過 web dom 的強綁定。父子間都是透過 props 做為資料傳遞,並無向上傳遞。
📌 框架本質的不同
Vue 本質是 MVVM 框架(漸進式框架),由 MVC 發展而來;
React 是前端元件化框架,由後端元件化發展而來。
📌 個人感受小結
Vue 的優勢
React 的優勢
其實當時在學習 React 時,一開始確實花了一些時間理解,但其實並沒有感受太大的進入障礙,可能很大一部分原因跟我個人很喜歡 JS 有關,再加上是以 React 的 Function Component 寫法開發,理解基本的 hook 如何使用後,就算不看文檔也可以順利開發,不會有太大的問題。
但進入 Vue ,因為有各種各樣的 api 操作,雖然起手簡單,但要能夠熟練以至於提高開發效率,過程需要需要不斷翻看文檔明白各項配置才真的能上手。而相較於此,React 沒有所謂這些林林總總的 api,因此學習起來,反而感覺 React 像是一張可以自由揮灑的白紙,而 Vue 則像是積木,你必須知道各種 api 的使用方式,知道哪裡該卡哪裡,才可以將整個畫面構件出來。
那我比較喜歡哪一種呢?
老實說我還是喜歡 React 。但 Vue 的靈活及相較於 React 的手動操作,Vue 自動響應的變化,還是令人驚嘆尤雨溪這位大神大概真的是神吧!
📌 參考資源
📌 延伸閱讀
The text was updated successfully, but these errors were encountered: