通過框架設計理解React、Angular、Vue區別

前言

我們已經通過學習掌握了vue.js這個漸進式的JavaScript 框架,並且大致知道了React、Angular和Vue的區別,那麼如何對這三個框架進行深層次的分析,更好地區分它們呢?我們可以從框架設計上入手試着分析它們。

什麼是框架

可以參考我之前的文章關於基於框架搭建與佈局系統的思考

框架設計

一、職責範圍

職責範圍就是框架設計之初要考慮的範圍,是一手全包還是隻封裝底層核心代碼?簡單說就是這個框架可以爲你做多少事情

1.small scope(小職責範圍)

代表:React
(1)設計理念:
自底向上
只建立核心模型,然後圍繞核心模型建立生態系統
(2)優點:
  • 初始時需要理解的概念很少

初始只用掌握核心代碼

  • 靈活
    因爲框架/庫只提供了部分底層的原生實現,用戶可以在框架基礎上構建任意複雜的系統
  • 生態好

擁有強大的生態系統

  • 維護成本小
(3)缺點:
  • 學習成本大

1.同樣也是因爲框架只提供了部分底層的原生實現,所以當我們需要構建比較複雜的系統時,就需要用非常有限的、非常原始的一些東西,去構建一些複雜的想法。(如學習了React,還需鑽研Redux、HOC 高階組件、render、props、Hooks以及在 JS 中使用 CSS 的各種方式等等)
2.官方只提供基礎的文檔,其餘需要自己去鑽研,需要自主學習能力

2.large scope(大職責範圍)

代表:Angular
(1)設計理念
自上而下
儘可能考慮用戶可能會遇到的問題;當你嘗試解決一個問題時,你在框架內就能找到解決方案。
(2)優點
  • 框架與生態一致性

集中式的設計確保了它本身與其生態系統的。當你遇到一個具體問題的時候,你不必去找一些不同的解決方案,你只需要看看框架它讓你做什麼,最大的可能就是它(框架)對此已經有解決方案。

  • 少量代碼解決最常見的問題

可以通過構建抽象概念來解決最常見的問題,如只需要建一個路由、一個http請求數據就能實現基本功能。

(3)缺點
  • 更高的學習門檻

對於初學者來說,如果沒有類似使用 Java 或者 C# 等語言經驗的話,而是僅僅只學過 HTML/CSS 以及 JavaScript 的話,當你看到 Angular 文檔的時候,你可能會很難吃透。

  • 不靈活

如果框架內置的解決方案不滿足當前需求,但卻沒有方法替換。
當你想嘗試更改底層想法時,它會影響到你項目中的每個組件(牽一髮而動全身)。

3.progressive scope(漸進式框架)

代表:Vue
(1)設計理念
框架分層
允許以漸進的方式選擇特性。如需要路由、需要狀態管理就引入,不需要也不影響,按需取捨,既能開發全新應用,也能融合之前已開發應用
(2)優點
  • 降低了學習門檻
(3)缺點

作爲small scope 和 large scope的中間者,需要去權衡利弊

  • 生態系統可能不會像小職責範圍那樣多樣化
  • 維護負擔幾乎與大職責範圍相同

二、渲染機制

如何表達你的視圖層,框架如何處理代碼?如何將實際渲染東西展示到頁面上的?這就要考慮我們的渲染機制。

1.原生DOM

原生DOM大家都熟悉,在這裏我就不過多說明了。

<div>
  <p class="framework-design">框架設計</p>
</div>
(1)優點
  • 易用性強
(2)缺點

在我們對原生DOM進行操作時,會發現很多缺點

  • 效率低
  • 解析速度慢
  • 內存佔用量高

2.JSX / VDOM(虛擬DOM)

通過框架來表現自己的UI結構

render() {
    return h(
        'div',
        null,
        h(
            'p',
            {  'class': 'framework-design' },
           '框架設計'
        )
    );
}
(1)優點
  • 通過JS實現UI層,具有 JavaScript 的完整表現力
  • 將視圖層視爲數據,可以對數據做任何操作
  • 可以渲染到任何目標,終端、PDF、Canvas、WebGL
(2)缺點
  • VDOM 本身成本很高

即使你只有一個節點,也可能會觸發 這個VDOM 的 Diff 算法

3.templates(模板編譯)

通過模板來表現自己的UI結構

<template>
  <div>
    <p>{{ data.title }}</p>
    <p>{{ data.content }}</p>
  </div>
</template>
(1)優點
  • 更加直接的渲染指令,具有更好的原生性能

通過模板編譯符準確知道可變的dom節點

<div>
  <p>框架設計</p>
  <p>{{ message }}</p>
</div>
(2)缺點
  • 受限於嚴格的模板語法,從而失去 JavaScript 的表達能力

三、狀態機制

1.髒檢查

髒數據:產生了變化的數據
髒檢查:找出髒數據,重新渲染視圖

那麼在什麼時候進行髒檢查呢?檢查哪些元素呢?

下面以Angular爲例

何時進行

Angular 會在可能觸發 UI 變更的時候進行髒檢查。例如常用的 ng-click。

檢查哪些元素

Angular 會對所有綁定到 UI 上的表達式做髒檢查。在Angular程序初始化時,會將綁定的對象的屬性添加爲監聽對象(watcher),也就是說一個對象綁定了N個屬性,就會添加N個watcher。

如何操作

當髒檢查觸發,則會循環遍歷所有watch,最後更新DOM

通俗點講

我們回憶一下我們的學生時代,住校生都住在寢室裏面,每棟宿舍樓都有專門的宿管阿姨。每天晚上快熄燈的時候(觸發髒檢查了),宿管阿姨開始巡邏了,她要看哪些學生還沒回寢室呢,寢室有哪些違規現象呢。阿姨會從1樓開始一直巡邏查看到頂樓,每間宿舍都要查看(循環遍歷watcher)。但是呢,因爲目前頂樓還沒住人,所以阿姨巡邏時會跳過(只檢查綁定到UI上的表達式)。最後啊,沒回寢的學生都被阿姨拿上小本本記下來了(查出了髒數據)。

2.依賴追蹤

當某一個數據(依賴數據)發生變化的時候,所有依賴這個數據的“相關”數據“自動”發生變化,也就是自動調用相關的函數去實現數據的變動,也就是數據驅動。

下面以Vue爲例

何時進行

依賴數據發生變化

如何操作

爲數據定義 getter & setter
當在data裏面定義了數據時,系統會爲這些數據添加getter和setter
獲取數據時觸發getter,爲數據賦值時觸發setter
當觸發了setter時,model發生變化,系統會通知所有的viewModel更新視圖

通俗點講

在我們大學時期,上課還是相對而言較嚴格的,爲了應對各項嚴格的規章制度,417寢室的室友們商量拉了一個微信羣(依賴數據:微信羣),當有重大事情時在羣裏面進行通知(每個人都可以接收消息、發送消息 getter & setter)。

某天政治課,大家偷懶賴牀不去上課,只有小李一人去了教室,不一會兒,小李就在微信羣裏面發了一句話“老師在點名!速來!”(set,更改了model,通知了所有的viewModel)。接收到消息的所有室友迅速起牀飛奔去教室(監聽到依賴數據發生變化,自動更新視圖)。

3.VDOM diff

保存上次的VDOM,對比這次的VDOM,發現差異,更改視圖
下面以React爲例

何時進行

state 發生改變

如何操作

比較兩次的VDOM,層層遍歷,找出不同的數據,更新整個DOM

通俗點講

大學每年最痛苦的就是期末了,期末時各個同學打起十二分的精神,搶佔各個樓道口,通宵達旦的背書看題。這個時候少不了老師劃的重點,政治課老師劃完重點後,小熊還不放心,去找上一屆的學長討來了學長那一屆的重點,回到寢室就開始一章一章地對比,從書的第一頁翻到了最後一頁(比較兩次VDOM),把不同的地方都標記出來(找出不同的數據),最後把比較過後的整本書都背了下來(更新整個DOM)。

總結

通過以上我們可以看出

1.React

是自底向上的框架。
它只提供部分底層的原生實現,擁有強大的生態環境。
使用JSX / VDOM 來渲染視圖層。
使用VDOM diff更新視圖,通常整個DOM都要重新渲染過。
學習成本很高,雖然初始上手很快,但如果想要實現更爲複雜的系統,需要鑽研Redux、HOC 高階組件、render、props、Hooks等知識。

2.Angular

是自上而下的框架。
使用templates和JSX / VDOM實現視圖層。
採用髒檢查更新視圖,設置多個watcher,當watcher越多時會耗費性能。
學習門檻高,不利於初學者。
組件豐富,一般常見的功能都在框架裏能找到解決方案。
二次開發成本高,當想實現底層想法時,會影響很多組件。

3.Vue

漸進式框架。
使用templates和JSX / VDOM實現視圖層。
採用數據驅動更新視圖,有變化才更新,提升效率。
易上手,靈活性強,既能開發全新應用,又能融合進已有應用中。
性能高,超快虛擬DOM
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章