- 從最開始學(xué)習(xí)
React
就接觸到Flux
架構(gòu),接著前端組件化框架都涉及到Flux
概念杰刽,例如Vue.js
中的Vuex
。一直以來Flux
都不是很好理解贺嫂,但俗話說實(shí)踐出真知,只有在真正的項(xiàng)目場景上使用過了第喳,才知道一個架構(gòu)概念為什么要如此設(shè)計(jì),可以帶來什么樣的好處曲饱。
Flux定義
-
Flux
是一種架構(gòu)思想,用來解決軟件結(jié)構(gòu)問題扩淀。 -
Flux
將一個應(yīng)用分成四個部分:
View: 視圖層
Action(動作):視圖層發(fā)出的消息(比如mouseClick)
Dispatcher(派發(fā)器):用來接收Actions、執(zhí)行回調(diào)函數(shù)
Store(數(shù)據(jù)層):用來存放應(yīng)用的狀態(tài)引矩,一旦發(fā)生變動侵浸,就提醒Views要更新頁面
用一張流程圖來表示:
- 在
Flux
中氛谜,數(shù)據(jù)是單向流動的:
- 用戶訪問 View
- View 發(fā)出用戶的 Action
- Dispatcher 收到 Action,要求 Store 進(jìn)行相應(yīng)的更新
- Store 更新后值漫,發(fā)出一個"change"事件
- View 收到"change"事件后,更新頁面
一個實(shí)踐和理解
- 上面的定義在網(wǎng)上一搜就有杨何。但相信很多人一開始和我一樣,定義看的懂危虱,但并不理解為什么要這么做,這樣做可以帶來什么好處埃跷?接下來試著用一個在實(shí)際項(xiàng)目中的場景來說明一下。
業(yè)務(wù)場景
- 界面有兩個大區(qū)域組成:
- 頂部
Header
:顯示當(dāng)前操作的公司名稱- 下部
Workplace
:主要功能工作區(qū)弥雹,包含一個Tab
組件。
-
Workplace
中第一個Tab
是公司選擇功能:填寫公司名稱剪勿,點(diǎn)擊確定之后輸入的公司名稱成為全局變量,并且顯示在Header
中厕吉。 - 在其他Tab頁面中可以獲取到當(dāng)前設(shè)定的公司名稱值。
結(jié)構(gòu)設(shè)計(jì)
- 使用現(xiàn)在也非常流行的
Vue.js
+Vuex
來解決這個問題赴涵。 - 有一些前端模塊化框架經(jīng)驗(yàn)的同學(xué)應(yīng)該很容易想到:
- 把兩個主區(qū)域(
Header
,Workplace
)分成兩個模塊(兩個.vue
文件)。Tab
中的N個功能頁面也對應(yīng)著N個模塊(N個.vue
文件)髓窜。- 使用
route
實(shí)現(xiàn)點(diǎn)擊Tab
頁在Workplace
中切換不同的功能模塊。
-
實(shí)現(xiàn)的結(jié)構(gòu)大致如下:
- 那么現(xiàn)在的問題就是如何將在
CompanySelect.vue
中設(shè)置的公司名稱寄纵,傳給Header.vue
來展示脖苏。 - 按前端模塊化的思路,每個模塊(
.vue
或.jsx
)都有自己獨(dú)立的state
與props
來處理數(shù)據(jù)與界面渲染的綁定棍潘。 - 在這個功能場景下崖媚,可以通過
App.vue
在創(chuàng)建Header.vue
和CompanySelect.vue
模塊的時候,設(shè)定回調(diào)函數(shù)畅哑,在CompanySelect.vue
輸入公司名稱后,由回調(diào)函數(shù)把值最終傳給Header.vue
來顯示:
Flux化
- 按
Flux
的思路來重構(gòu):
- 一個項(xiàng)目(或者大模塊)將會確定一個根荠呐。
- 在這個根上擁有
state
和改變state
的事件方法。- 根之下的功能模塊“舍棄”自己的
state
泥张,數(shù)據(jù)的來源與變化改為根的state。- 功能模塊中的操作事件只會觸發(fā)根上的事件方法媚创,不實(shí)現(xiàn)具體的業(yè)務(wù)邏輯。
- 在這個例子中钞钙,
CompanySelect.vue
本身將不會保存公司名稱的變量,“確定”按鈕只把輸入的值通過事件傳給根(App.vue
)歇竟,由根進(jìn)行保存和傳遞給其他組件。
- 失去
state
和業(yè)務(wù)邏輯的功能模塊焕议,將會弱化成單純的顯示組件,所有的數(shù)據(jù)供給和業(yè)務(wù)邏輯由根來組裝提供盅安。 - 這種改變,有利于復(fù)雜項(xiàng)目的前端模塊化别瞭,實(shí)現(xiàn)顯示組件的復(fù)用化。