iT邦幫忙

2021 iThome 鐵人賽

DAY 10
0
Modern Web

Vue.js 進階心法系列 第 10

統一狀態管理 + 單一資料流

我一開始在學 Vuex 的時候,覺得很難懂,不知道它是在做什麼的。當時的我,就想先追朔單一資料流的始祖(應該是吧?) flux

Flux

它提出了不少更新畫面的理論與觀念,之後的 Redux 和 Vuex 使用的專有名詞,都和它的用詞有相關性。

撰寫本文時 flux 已進入維護模式,不建議使用了。

整體的模型長這樣。

由於這是 facebook 出的 pattern 所以上面都會講要和 React 整合。

這個圖的出發點在 User Interactions 網頁和使用者互動的時候,會呼叫 Action Creators ,在此處理非同步的 Web API 取得遠端伺服器上的資料。

經過中間的輾轉,將資料儲存在 Store。再經過 Change Events + Store Queries 將資料更新到畫面上。

資料的旅行

Dispatcher

  • 整個 application 唯⼀一的⼀一個 (singleton)
  • Store 向 Dispatcher 註冊通知變更更
  • Action 透過 Dispatcher 更更新 Store

Store

  • 每個 application 可擁有多個 store
  • 資料中⼼心
  • 透過 action 呼叫 mutate 更更改 store 的 data
  • no public setter, only getter
  • 資料改變發⽣生在 'change' event

Action

  • 定義內部 API
  • 動作中⼼心
  • 任何與 application 的互動⽅方式
  • 語意化命名⾏行行為

View (圖上是 ReactViews)

  • Data 從 Store 拿出來來顯⽰示
  • View 必須訂閱 store 的 change 事件
  • Action 也是由View 與使⽤用者⼾戶動⽽而觸發的

為什麼要單一資料流?

其實,只要宣告一個全域變數或物件,甚至做出 getter/setter 的抽象給物件使用,就足以管理這些全域的資料了,為什麼還要「單一資料流」呢?

其實,最主要的原因在於方便 debug ,如果一切都順利,是不是單資料流似乎不是這麼重要,但是萬一出錯了,是不是單一資料流就會是一件很重要的事情,它會將很多連續執行的資料設定,弄成由 dispacher 處理,一次處理一個。並且可以透過開發者工具看見。

透過一步一步的查詢,可以看得見哪一次賦值不如預期,所以造成問題。

沒有單一資料流的 AngularJS

在 AngularJS 中就有出現廣播的方式,每次呼叫都會通知程式碼呼叫它註冊好的 callback,而 dispatcher 其實是一種廣播系統,它限縮在一個可控的狀況。讓各處都可以呼叫註冊好的 callback。

雖然語法相同,但是用法不同,就會造成災難。
由於是廣播系統,所以有些人的用法就是直接從這個 view 呼叫另一個 view 的 method ,為的是原本更新資料沒有更新到的畫面,可以強制更新。

但也許更新資料本身並沒有遵守 immutable 的原則,所以才會出問題,而不需要呼叫強制更新。造成不必要的耦合。

AngularJS 也有 service 來處理共用的程式碼。但是正因為在那個時候也許單一資料流還不是顯學,所以沒有把這個東西做成一個套件。所以用 service 只是用來共用的人,就很難管理修改資料的前後順序與除錯的問題。

後來的 Vuex

使用了 dispatch 來呼叫 action
使用了 commit 來呼叫 mutation
使用了 getters 來呼叫 getters
使用了 state 來呼叫 state

接下來會花幾天的時間,慢慢的介紹,我自己如何看待 vuex 以及如何使用它。


上一篇
Component 鬼牌(二): 看網址決定 Component
下一篇
存放資料的 state、module
系列文
Vue.js 進階心法30

尚未有邦友留言

立即登入留言