最近開始接觸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出現的原因,且聽下回分解。
最後,以一張思維導圖結束本篇文章: