最近要開始搞網頁端錢包,本着幹一行愛一行的原則,擼起了前端框架。前端
項目基於螞蟻金服的dva框架,其實是對幾個流行的開源框架的整合,技術棧包括:react
在開始介紹以前,先說一說MV*。你們必定都據說過MVC,在這以後又衍生出了MVP和MVVM,這些均可以統稱爲MV*。可是,隨着前端代碼複雜度的增長,人們發現愈來愈難以管理程序的狀態,模塊之間耦合嚴重,代碼難以調試,所以不少人認爲「前端MVC已死」。編程
2014年,facebook提出了一個新的概念:Flux,旨在解決這些問題,其核心思想是「組件化 + 單向數據流」。這個框架很快流行了起來,而且逐漸成爲目前的主流前端框架之一。爲了更深入地理解這一變化,咱們來逐一比較一下它們之間的異同:redux
用戶首先經過View發起交互,View調用Controller執行業務邏輯,Controller修改Model,而後View經過觀察者模式檢測到Model的變化(具體表現形式能夠是Pub/Sub或者是觸發Events),刷新界面顯示。前端框架
從這裏能夠看出,主要業務邏輯都在Controller中,Controller會變得很重。MVC比較明顯的缺點:服務器
爲了克服MVC的上述缺點,MVP應運而生。在MVP中,View和Model是沒有直接聯繫的,全部操做都必須經過Presenter進行中轉。View向Presenter發起調用請求,Presenter修改Model,Model修改完成後通知Presenter,Presenter再調用View的相關接口刷新界面。這樣,View就不須要監聽具體Model的變化了,只須要提供接口給Presenter調用就能夠了。MVP具備如下優勢:antd
爲了進一步解放生產力,把Presenter中調用View的接口同步數據變化的重複工做抽象出來,作成一個binder模塊,這就變成了MVVM。開發者只須要指明綁定關係,binder模塊會自動完成數據同步,這就是所謂的「雙向數據流」,無論哪一端的數據發生變化,都會當即同步到另外一端。實際上,Vue.js、Angular這些流行的前端框架都使用了雙向數據流設計。react-router
雙向數據流極大地簡化了開發者的工做,可是詬病也隨之而來。因爲綁定的隨意性,某個View對Model進行的修改有可能會對其餘的View形成「連鎖反應」,再加上各類異步回調,給代碼調試形成了很大的困難,每每難以定位數據究竟是被誰修改掉的。用專業一點的術語來說,代碼的「可預測性」很是差。所以,爲了提升可預測性,不少人主張迴歸到「單向數據流」模式,其中的典型表明就是facebook的Flux框架。框架
其實Flux並非什麼新鮮事物,其背後仍是經典的MVC思想,可是實現方式上有所不一樣。Flux的核心是「組件化+單向數據流「,下面逐一進行介紹。異步
在傳統的MVC設計中,Model中不只要存儲應用程序數據,還須要存儲UI狀態。另外一方面,Controller中不只要處理業務邏輯,還須要實現各類事件處理邏輯。若是把這部份內容抽出來,和View組合在一塊兒,就變成了「組件」。這樣一來,各個模塊均可以各司其職,專一於本身的領域,代碼的可讀性和複用性均可以獲得提升。
在實際編程中,通常把純界面展現的View實現成一個「無狀態組件」,在其上層再包裝一個Controller-View(也能夠稱爲Container),專門監聽事件並更新數據,而後把數據做爲props傳遞給View。這種編程模式能夠最大程度地提升組件的可複用性。
爲了提升代碼的可預測性,Flux採用單向數據流設計。這裏引入了3個新概念:
當Store數據發生變化時,會發送一個事件,View或者Controller-View能夠監聽這個事件,而後完成界面刷新。整個過程是「單向」的,若是View想要繼續修改Store,必須從新發起一個Action。
固然,除了View之外,服務器或者Web API也能夠直接發送Action給Dispatcher,這就是爲何圖中Dispatcher有兩個輸入的緣由。
更爲詳細的Flux流程參見下圖:
經過以上分析能夠發現,所謂單向數據流並非什麼新鮮概念,實際上最最經典的MVC設計中,數據流就是單向的。雖然Flux官方宣稱它們不是MVC,但我我的認爲其實它實際想說的是MVVM,由於MVVM纔是雙向數據流。
固然,Flux也不是完美的,在多Store協同管理上存在必定的設計缺陷,這也是後來Redux出現的緣由,且聽下回分解。
最後,以一張思惟導圖結束本篇文章: