前端技術(一):從MV*到Flux

最近開始接觸react框架,然後學習了關於react周邊的一系列技術。

react全家桶包括了

react,組件化的框架,看官方文檔即可

react-router,路由管理

redux, 是一個狀態容器,提供可預測化的狀態管理

redux-saga,數據獲取等異步時間和訪問緩存

react-redux,redux的官方綁定

react-router-redux ,上面三者的結合體

,immutable, 創建不可變的數據

reselect,選擇器

antd ui框架  開箱即用的ui框架

Create raect-app  官方腳手架(集成react+react-dom+react-router)

Antd pro antd提供的腳手架

項目基於螞蟻金服的dva框架,實際上是對幾個流行的開源框架的整合,技術棧包括:

  • react

  • react-router

  • redux

  • redux-saga

  • dva

  • antd

有時候dva會結合umi使用:

Umi react應用開發框架,對下面等技術進行了封裝,主要負責路由 

{

  preact

Webpack

React-router

Babel

Jest

}

 

負責數據,DVA不添加新的語法,只是封裝了,不使用dva前,reducer, saga, action 都是分離的(分文件)

Dva  數據流前端框架,封裝了redux,redux-saga,react-router

{

    redux

   redux-saga

   react-route

   等

}

 

//負責組件開發,螞蟻金服提供的組件,用就是啦

antd

前後端分離的重要一角,現在很多工具可以快速生成這樣的模擬數據了,比如easymock

//負責搭建假數據

mock

發現前端真的是深不見底啊,越學越多,周邊的技術,讓你眼花繚亂。這些只是冰山一角,基於框架開發,慢慢對底層的東西會遺忘,底層的東西還是非常重要滴。

在開始介紹之前,先說一說MV*。大家一定都聽說過MVC,在這之後又衍生出了MVP和MVVM,這些都可以統稱爲MV*。但是,隨着前端代碼複雜度的增加,人們發現越來越難以管理程序的狀態,模塊之間耦合嚴重,代碼難以調試,因此很多人認爲“前端MVC已死”。

2014年,facebook提出了一個新的概念:Flux,旨在解決這些問題,其核心思想是“組件化 + 單向數據流”。這個框架很快流行了起來,並且逐漸成爲目前的主流前端框架之一。爲了更深刻地理解這一變化,我們來逐一比較一下它們之間的異同:

1.MVC

 

用戶首先通過View發起交互,View調用Controller執行業務邏輯,Controller修改Model,然後View通過觀察者模式檢測到Model的變化(具體表現形式可以是Pub/Sub或者是觸發Events),刷新界面顯示。

從這裏可以看出,主要業務邏輯都在Controller中,Controller會變得很重。MVC比較明顯的缺點:

  • View依賴特定的Model,無法組件化

  • View和Controller緊耦合,如果脫離Controller,View難以獨立應用(功能太少)

2.MVP

爲了克服MVC的上述缺點,MVP應運而生。在MVP中,View和Model是沒有直接聯繫的,所有操作都必須通過Presenter進行中轉。View向Presenter發起調用請求,Presenter修改Model,Model修改完成後通知Presenter,Presenter再調用View的相關接口刷新界面。這樣,View就不需要監聽具體Model的變化了,只需要提供接口給Presenter調用就可以了。MVP具有以下優點:

  • View可以組件化,不需要了解業務邏輯,只需提供接口給Presenter

  • 便於測試:只需要給Presenter mock一個View,實現View的接口即可

3.MVVM

爲了進一步解放生產力,把Presenter中調用View的接口同步數據變化的重複工作抽象出來,做成一個binder模塊,這就變成了MVVM。開發者只需要指明綁定關係,binder模塊會自動完成數據同步,這就是所謂的“雙向數據流”,不管哪一端的數據發生變化,都會立即同步到另一端。實際上,Vue.js、Angular這些流行的前端框架都使用了雙向數據流設計。

雙向數據流極大地簡化了開發者的工作,但是詬病也隨之而來。由於綁定的隨意性,某個View對Model進行的修改有可能會對其他的View造成“連鎖反應”,再加上各種異步回調,給代碼調試造成了很大的困難,往往難以定位數據到底是被誰修改掉的。用專業一點的術語來講,代碼的“可預測性”非常差。因此,爲了提高可預測性,很多人主張迴歸到“單向數據流”模式,其中的典型代表就是facebook的Flux框架。

4.Flux

其實Flux並不是什麼新鮮事物,其背後還是經典的MVC思想,但是實現方式上有所不同。Flux的核心是“組件化+單向數據流“,下面逐一進行介紹。

4.1組件化

在傳統的MVC設計中,Model中不僅要存儲應用程序數據,還需要存儲UI狀態。另一方面,Controller中不僅要處理業務邏輯,還需要實現各種事件處理邏輯。如果把這部分內容抽出來,和View組合在一起,就變成了“組件”。這樣一來,各個模塊都可以各司其職,專注於自己的領域,代碼的可讀性和複用性都可以得到提高。

在實際編程中,一般把純界面展示的View實現成一個“無狀態組件”,在其上層再包裝一個Controller-View(也可以稱爲Container),專門監聽事件並更新數據,然後把數據作爲props傳遞給View。這種編程模式可以最大程度地提高組件的可複用性。

4.2單向數據流

爲了提高代碼的可預測性,Flux採用單向數據流設計。這裏引入了3個新概念:

  • Store:每個程序可以擁有多個Store,存儲應用程序狀態的不同部分。Store對View是隻讀的,只有Dispatcher可以通過Store註冊的回調函數修改Store的內容

  • Action:當發生交互,需要修改Store內容時,需要發起一個Action,包含對應的type和payload

  • Dispatcher:當接收到Action時,會通過回調函數調用所有Store的,完成數據修改

當Store數據發生變化時,會發送一個事件,View或者Controller-View可以監聽這個事件,然後完成界面刷新。整個過程是“單向”的,如果View想要繼續修改Store,必須重新發起一個Action。

當然,除了View以外,服務器或者Web API也可以直接發送Action給Dispatcher,這就是爲什麼圖中Dispatcher有兩個輸入的原因。

更爲詳細的Flux流程參見下圖:

通過以上分析可以發現,所謂單向數據流並不是什麼新鮮概念,實際上最最經典的MVC設計中,數據流就是單向的。雖然Flux官方宣稱它們不是MVC,但我個人認爲其實它實際想說的是MVVM,因爲MVVM纔是雙向數據流。

當然,Flux也不是完美的,在多Store協同管理上存在一定的設計缺陷,這也是後來Redux出現的原因,且聽下回分解。

最後,以一張思維導圖結束本篇文章:

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章