淺析React&Vue兩大流行框架優(yōu)缺點

  • vue - 本質(zhì)是 MVVM 框架幅垮,由 MVC 發(fā)展而來
  • React - 本質(zhì)是前端組件化框架,不是一個完整的MVC框架蜗侈,可以認(rèn)為是MVC中的V(View)

MVVM

MVVM 的出現(xiàn)促進了 GUI 前端開發(fā)與后端業(yè)務(wù)邏輯的分離,極大地提高了前端開發(fā)效率。MVVM 的核心是 ViewModel 層沥阳,它就像是一個中轉(zhuǎn)站(value converter),負(fù)責(zé)轉(zhuǎn)換 Model 中的數(shù)據(jù)對象來讓數(shù)據(jù)變得更容易管理和使用自点,該層向上與視圖層進行雙向數(shù)據(jù)綁定桐罕,向下與 Model 層通過接口請求進行數(shù)據(jù)交互,起呈上啟下作用。如下圖所示

mvvm1.png

MVVM的設(shè)計思想:關(guān)注Model的變化功炮,讓MVVM框架去自動更新DOM的狀態(tài)溅潜,從而把發(fā)者從操作DOM的繁瑣步驟中解脫出來!

  • Bug很難被調(diào)試薪伏。因為使用雙向綁定的模式滚澜,當(dāng)你看到界面異常了,有可能是你View的代碼有Bug嫁怀,也可能是Model的代碼有問題博秫。數(shù)據(jù)綁定使得一個位置的Bug被快速傳遞到別的位置,要定位原始出問題的地方就變得不那么容易了眶掌。另外挡育,數(shù)據(jù)綁定的聲明是指令式地寫在View的模版當(dāng)中的,這些內(nèi)容是沒辦法去打斷點debug的朴爬。

  • 一個大的模塊中model也會很大即寒,雖然使用方便了也很容易保證了數(shù)據(jù)的一致性,當(dāng)時長期持有召噩,不釋放內(nèi)存就造成了花費更多的內(nèi)存母赵。

  • 對于大型的圖形應(yīng)用程序,視圖狀態(tài)較多具滴,ViewModel的構(gòu)建和維護的成本都會比較高凹嘲。

yuanli.jpeg

生命周期

Vue生命周期

vue-life.png

React為每個組件提供了生命周期鉤子函數(shù)去響應(yīng)不同的時刻,組件的生命周期分為三個部分:(1)實例化构韵;(2)存在期周蹭;(3)銷毀&清理期。具體周期如下圖所示:

React v16.3以前版本

reacct.16.3-down.png

React v16.3以后版本

react-16.3-up.jpeg

數(shù)據(jù)流管理

Vue組件數(shù)據(jù)流的問題

而vue的思想是響應(yīng)式的疲恢,也就是基于是數(shù)據(jù)可變的凶朗,通過對每一個屬性建立Watcher來監(jiān)聽,當(dāng)屬性變化的時候显拳,響應(yīng)式的更新對應(yīng)的虛擬dom棚愤。

vue-parent_child.png

React數(shù)據(jù)是單向不可變的

react是自上而下的單向組件數(shù)據(jù)流,容器組件&展示組件(也叫傻瓜組s件&聰明組件)是最常用的react組件設(shè)計方案杂数,容器組件負(fù)責(zé)處理復(fù)雜的業(yè)務(wù)邏輯以及數(shù)據(jù)宛畦,展示組件負(fù)責(zé)處理UI層,通常我們會將展示組件抽出來進行復(fù)用或者組件庫的封裝揍移,容器組件自身通過state來管理狀態(tài)次和,setState更新狀態(tài),從而更新UI羊精,通過props將自身的state傳遞給展示組件實現(xiàn)通信斯够。

這是當(dāng)業(yè)務(wù)需求不復(fù)雜,頁面較簡單時我們常用的數(shù)據(jù)流處理方式喧锦,僅用react自身提供的props和state來管理足矣读规,但是如果稍微增加一點復(fù)雜度呢,比如當(dāng)我們項目中遇到這些問題:

state-props.jpg

1燃少,如何實現(xiàn)跨組件通信束亏、狀態(tài)同步以及狀態(tài)共享?

react V16.3以前阵具,通過狀態(tài)提升至最近的共同父組件來實現(xiàn)碍遍。(雖然有官方提供的context API,但是舊版本存在一個問題:看似跨組件阳液,實則還是逐級傳遞怕敬,如果中間組件使用了ShouldComponentUpdate檢測到當(dāng)前state和props沒有變化,return false帘皿,那么context就會無法透傳东跪,因此context沒有被官方推薦使

react.png

react V16.3版本以后,新版本context解決了之前的問題鹰溜,可以輕松實現(xiàn)虽填,但依然存在一個問題,context也是將底部子組件的狀態(tài)控制交給到了頂級組件曹动,但是頂級組件狀態(tài)更新的時候一定會觸發(fā)所有子組件的re-render斋日,那么也會帶來損耗。(雖然我們可以通過一些手段來減少重繪墓陈,比如在中間組件的SCU里進行一些判斷恶守,但是當(dāng)項目較大時,我們需要花太多的精力去做這件事)

context.png

2贡必,如何避免組件臃腫熬的?

當(dāng)某個組件的業(yè)務(wù)邏輯非常復(fù)雜時,我們會發(fā)現(xiàn)代碼越寫越多赊级,因為我們只能在組件內(nèi)部去控制數(shù)據(jù)流押框,沒辦法抽離,Model和View都放在了View層理逊,整個組件顯得臃腫不堪橡伞,業(yè)務(wù)邏輯統(tǒng)統(tǒng)堆在一塊,難以維護晋被。

3兑徘,如何讓狀態(tài)變得可預(yù)知,甚至可回溯羡洛?

當(dāng)數(shù)據(jù)流混亂時挂脑,我們一個執(zhí)行動作可能會觸發(fā)一系列的setState,我們?nèi)绾文軌蜃屨麄€數(shù)據(jù)流變得可“監(jiān)控”,甚至可以更細(xì)致地去控制每一步數(shù)據(jù)或狀態(tài)的變更崭闲?

4肋联,如何處理異步數(shù)據(jù)流?

react自身并未提供多種處理異步數(shù)據(jù)流管理的方案刁俭,僅用一個setState已經(jīng)很難滿足一些復(fù)雜的異步流場景橄仍;

組件通信

component-props.png

其實這部分兩個比較相似。在Vue 中有三種方式可以實現(xiàn)組件通信:

  • 父組件通過props向子組件傳遞數(shù)據(jù)或者回調(diào)牍戚,雖然可以傳遞回調(diào)侮繁,但是我們一般只傳數(shù)據(jù),只需通過事件的機制來處理
  • 子組件向父組件的通信子組件通過事件 向父組件發(fā)送消息
  • 通過 V2.2.0 中新增的 provide/inject 來實現(xiàn)父組件向子組件注入數(shù)據(jù)如孝,可以跨越多個層級宪哩。
  • 訪問parent/children等不合編碼規(guī)范的方式。

在React中第晰,組件是如何通信的呢斋射?

  • 父組件通過 props 可以向子組件傳遞數(shù)據(jù)或者回調(diào)
  • 通過 context 進行跨層級的通信,這其實和 provide/inject 起到的作用差不多但荤。

React不支持自定義事件罗岖,Vue中子組件向父組件傳遞消息有兩種方式:事件和回調(diào)函數(shù),而且Vue更傾向于使用事件腹躁。但是在 React 中我們都是使用回調(diào)函數(shù)的桑包,這可能是他們二者最大的區(qū)別。

模版上不同

  • vue - 使用模板(最初由 angular 提出)
  • React - 使用 JSX

條件判斷

template.png

循環(huán)遍歷生成

template2.png

JSX

template3.png

總結(jié)

  • 模板語法上纺非,我更加傾向于 JSX
  • 模板分離上哑了,我更加傾向于 vue

補充說明

  • JSX 語法(標(biāo)簽、JS 表達(dá)式烧颖、判斷弱左、循環(huán)、事件綁定)
  • JSX 是語法糖炕淮,需被解析成 JS 才能運行
  • JSX 是 React 引入的拆火,但不是 React 獨有的, 是獨立的標(biāo)準(zhǔn)涂圆,可被其他項目使用

VDOM

React

React在開發(fā)初期就引入虛擬DOM概念们镜,后來發(fā)現(xiàn)很好用,但是這是一個無心插柳的結(jié)果润歉, 但React的核心思想:組件化模狭,一個Component拯救世界,忘掉煩惱踩衩,從此不再操心界面嚼鹉。

為什Virtual Dom快? Javascript很快, Dom很慢 ~

vue:Vue在2.0版本引入了vdom贩汉。其vdom是基于snabbdom 庫所做的修改。snabbdom是一個開源的vdom庫锚赤。snabbdom的主要作用就是將傳入的JS模擬的DOM結(jié)構(gòu)轉(zhuǎn)換成虛擬的DOM節(jié)點匹舞。先通過其中的 h函數(shù) 將JS模擬的DOM結(jié)構(gòu)轉(zhuǎn)換成虛擬DOM之后,再通過其中的 patch函數(shù) 將虛擬DOM轉(zhuǎn)換成真實的DOM渲染到頁面中宴树。為了保證頁面的最小化渲染策菜,snabbdom引入了Diff算法 晶疼,通過Diff算法找出前后兩個虛擬DOM之間的差異酒贬,只更新改變了的DOM節(jié)點,而不重新渲染為改變的DOM節(jié)點翠霍。

<!DOCTYPE html>
<html lang="en">
 <head> 
  <meta charset="UTF-8" /> 
  <meta name="viewport" content="width=device-width, initial-scale=1.0" /> 
  <meta http-equiv="X-UA-Compatible" content="ie=edge" /> 
  <title>Document</title>
 </head>
 <body> 
  <p id="container"></p> 
  <button id="btn-change">change</button> 
  <!-- 引入snabbdom庫锭吨,先不必糾結(jié)為什么這樣引入,以及每個文件的作用寒匙。 --> 
  <script src="https://cdn.bootcss.com/snabbdom/0.7.1/snabbdom.js"></script> 
  <script src="https://cdn.bootcss.com/snabbdom/0.7.1/snabbdom-class.js"></script> 
  <script src="https://cdn.bootcss.com/snabbdom/0.7.1/snabbdom-props.js"></script> 
  <script src="https://cdn.bootcss.com/snabbdom/0.7.1/snabbdom-style.js"></script> 
  <script src="https://cdn.bootcss.com/snabbdom/0.7.1/snabbdom-eventlisteners.js"></script> 
  <script src="https://cdn.bootcss.com/snabbdom/0.7.1/h.js"></script> 
  <script>
    //定義patch函數(shù)
    var patch = snabbdom.init([
        snabbdom_class,
        snabbdom_props,
        snabbdom_style,
        snabbdom_eventlisteners
    ])       
    //定義h函數(shù)
    var h = snabbdom.h;      
    //生成一個vnode    
    var vnode = h('ul#list',{},[
        h('li.item',{},['Item 1']),
        h('li.item',{},['Item 2']),
    ])
  console.log(vnode);  
    //獲取container
    var container = document.getElementById('container');
    patch(container,vnode);//初次渲染
    var btn = document.getElementById('btn-change');
    btn.onclick = function() {  
        var newVnode = h('ul#list',{},[
            h('li.item',{},['Item 1']),
            h('li.item',{},['Item B']),
            h('li.item',{},['Item 3']),
        ])
        patch(vnode,newVnode);//再次渲染
        vnode = newVnode;//將修改后的newVnode賦值給vnode    
   } 
    </script>  
 </body>
</html>

vue中的模板解析和渲染的核心就是:通過類似snabbdom的h()和patch()的函數(shù)零如,先將模板解析成vnode,如果是初次渲染锄弱,則通過patch(container,vnode)將vnode渲染至頁面考蕾,如果是二次渲染,則通過patch(vnode,newVnode)会宪,先通過Diff算法比較原vnode和newVnode的差異肖卧,以最小的代價重新渲染頁面。

組件化的區(qū)別

  • React 本身就是組件化掸鹅,沒有組件化就不是 React
  • vue 也支持組件化塞帐,不過是在 MVVM 上的擴展
  • 對于組件化,我更加傾向于 React 巍沙,做的徹底而清晰

共同點

  • 都支持組件化
  • 都是數(shù)據(jù)驅(qū)動試圖

Chrome 開發(fā)工具

React和Vue都有很好的Chrome擴展工具去幫助你找出bug葵姥。它們會檢查你的應(yīng)用,讓你看到Vue或者React中的變化句携。你也可以看到應(yīng)用中的狀態(tài)榔幸,并實時看到更新。

DEMO展示

參考文章:

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末矮嫉,一起剝皮案震驚了整個濱河市牡辽,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌敞临,老刑警劉巖态辛,帶你破解...
    沈念sama閱讀 216,651評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異挺尿,居然都是意外死亡奏黑,警方通過查閱死者的電腦和手機炊邦,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,468評論 3 392
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來熟史,“玉大人馁害,你說我怎么就攤上這事□迤ィ” “怎么了碘菜?”我有些...
    開封第一講書人閱讀 162,931評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長限寞。 經(jīng)常有香客問我忍啸,道長,這世上最難降的妖魔是什么履植? 我笑而不...
    開封第一講書人閱讀 58,218評論 1 292
  • 正文 為了忘掉前任计雌,我火速辦了婚禮,結(jié)果婚禮上玫霎,老公的妹妹穿的比我還像新娘凿滤。我一直安慰自己,他們只是感情好庶近,可當(dāng)我...
    茶點故事閱讀 67,234評論 6 388
  • 文/花漫 我一把揭開白布翁脆。 她就那樣靜靜地躺著,像睡著了一般鼻种。 火紅的嫁衣襯著肌膚如雪反番。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,198評論 1 299
  • 那天普舆,我揣著相機與錄音恬口,去河邊找鬼。 笑死沼侣,一個胖子當(dāng)著我的面吹牛祖能,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播蛾洛,決...
    沈念sama閱讀 40,084評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼养铸,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了轧膘?” 一聲冷哼從身側(cè)響起钞螟,我...
    開封第一講書人閱讀 38,926評論 0 274
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎谎碍,沒想到半個月后鳞滨,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,341評論 1 311
  • 正文 獨居荒郊野嶺守林人離奇死亡蟆淀,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,563評論 2 333
  • 正文 我和宋清朗相戀三年拯啦,在試婚紗的時候發(fā)現(xiàn)自己被綠了澡匪。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,731評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡褒链,死狀恐怖唁情,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情甫匹,我是刑警寧澤甸鸟,帶...
    沈念sama閱讀 35,430評論 5 343
  • 正文 年R本政府宣布,位于F島的核電站兵迅,受9級特大地震影響抢韭,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜喷兼,卻給世界環(huán)境...
    茶點故事閱讀 41,036評論 3 326
  • 文/蒙蒙 一篮绰、第九天 我趴在偏房一處隱蔽的房頂上張望后雷。 院中可真熱鬧季惯,春花似錦、人聲如沸臀突。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,676評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽候学。三九已至藕筋,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間梳码,已是汗流浹背隐圾。 一陣腳步聲響...
    開封第一講書人閱讀 32,829評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留掰茶,地道東北人暇藏。 一個月前我還...
    沈念sama閱讀 47,743評論 2 368
  • 正文 我出身青樓,卻偏偏與公主長得像濒蒋,于是被迫代替她去往敵國和親盐碱。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,629評論 2 354

推薦閱讀更多精彩內(nèi)容

  • Vue也已經(jīng)升級到2.0版本了沪伙,到現(xiàn)在為止(2016/11/19)比較流行的MVVM框架有AngularJS(也有...
    彬_仔閱讀 27,219評論 12 114
  • 以下內(nèi)容是我在學(xué)習(xí)和研究React時瓮顽,對React的特性、重點和注意事項的提取围橡、精練和總結(jié)暖混,可以做為React特性...
    科研者閱讀 8,232評論 2 21
  • 轉(zhuǎn)自 http://caibaojian.com/vue-vs-react.html#commentsVue和Re...
    嫌疑人螺某閱讀 789評論 0 0
  • 去年下半年,公司的主營業(yè)務(wù)由軟件開發(fā)轉(zhuǎn)型做移動互聯(lián)網(wǎng)運營翁授,做了5年商務(wù)工作的我不得不面臨著業(yè)務(wù)轉(zhuǎn)型帶來的一系...
    禾苗青青閱讀 737評論 1 3
  • 陪旺旺打耳洞拣播,像我小時候一樣會發(fā)炎善绎,倒頭在我床上哆啦陪著呼呼大睡,一秒入睡诫尽,昨晚的散步旺也沒參與禀酱,跟歐倆人討論了流...
    TX故事閱讀 426評論 2 7