Vuex 的應用場景

本文在 GitHub上的連接vue

昨天被問了一個問題:git

Vuex 的應用場景有什麼?何時適合使用 Vuex,何時不適合使用 Vuex?github

在當時,個人答案是通常人會回答的內容:vuex

  1. 涉及到非父子關係的組件,例如兄弟關係、祖孫關係,甚至更遠的關係;
  2. 他們之間若是有數據交互,那麼應該使用Vuex來實現;
  3. 若是頁面複雜度比較低的話,也能夠考慮使用 global-event-bus 來實現;
  4. 若是隻是父子關係的組件數據交互,那麼應該考慮使用props進行單向傳遞;
  5. 若是涉及到子組件向父組件的數據傳遞,那麼應該考慮使用 $emit$on

講道理說,這個答案也不算錯,當時我也只能回想起這些。cookie

但後來,我又想了想,其實還能夠更有針對性一些。session

例如,在如下場景裏,咱們應當使用 Vuex:異步

一、組件會被銷燬this

咱們能夠假設這樣一個場景:spa

  1. 假若有這樣一個組件,他是彈窗,有一些複選框和輸入框,用戶會選擇和填寫信息;
  2. 而後這個彈窗會被關閉和打開,因爲業務須要,這個彈窗輸入的內容,但願關閉後能夠保留,在從新打開後,內容依然存在。

解決辦法:code

  1. 咱們能夠考慮將值存在父組件中,也就是說,實際修改的是父組件的值;
  2. 存在好比 sessionStoragecookies之類的裏面,在 created 時從中讀取,destroyed的時候寫入其中;
  3. 能夠存到 global-event-bus 裏面;

但事實上,最好的仍是存在 Vuex 裏:

  1. 能夠直接經過 $store.state 來調用,經過 commit() 來修改值;
  2. 也能夠在 created 的時候,讀取存在 state 裏面的值,在 destroyed 的時候,寫回 state;

這樣處理的優勢是解耦,不跟其餘組件打交道。

二、組件基於數據而建立

咱們能夠假設這樣一個場景:

  1. 用戶登陸後,讀取權限配置表,這顯然是一個異步操做;
  2. 這個配置表可能會影響不少頁面。好比被影響的組件的加載條件,例如是 v-if="$store.state.userInfo.superVIP

那麼:

  1. 由於讀取權限配置表這個異步操做,可能影響多個組件,而這些組件之間的關係,顯然是不可預料的(即不必定是在同一個父組件下面);
  2. 那麼這個異步操做,寫在某一個組件裏就不太合適(由於其餘組件讀取這個組件很不方便,即便他是根組件);

解決辦法:

  1. 一個妥協的解決辦法,是寫在 global-event-bus 裏面來實現;
  2. 可是顯然,更好的解決辦法是寫在 vuex 裏面更專業一些;

三、多對多事件——多處觸發,影響多處

咱們能夠假設這樣一個場景:

  1. 假若有一個事件,好比:切換頁面顯示風格,他將改變某一個變量的值;
  2. 當該變量爲 true 時,那麼頁面風格爲白天(主要影響 v-bind:style 的值);
  3. 當該變量爲 false 時,那麼頁面風格爲晚上(同上);
  4. 在多個地方能夠切換這個頁面風格開關;
  5. 毫無疑問,這個變量將影響多個地方的 v-bind:style 的值;
  6. 這就是 多對多 場景;

那麼:

  1. 不管這個變量放在哪一個組件裏,其餘組件調用他都是很麻煩的事情;
  2. 即便存於根組件,而後經過 this.$root.xx 來獲取這個變量,也是很麻煩的,並且很醜陋;

解決辦法:

  1. 若是不使用 Vuex,那麼咱們可能會去考慮使用 global-event-bus 來存儲這個變量,並使用它;
  2. 這不是不能夠,但不優雅,並且管理麻煩;
  3. 而使用 Vuex,那麼這就是一件很方便的事情了;
  4. 咱們能夠經過 $store.state.xxx 來獲取這個變量的值;
  5. 經過 $store.getters.yyy 來獲取某些基於這個值的,表示通用樣式(例如黑底白字)的對象;
  6. 經過 $store.commit() 來提交修改(好比在某些狀況下能夠禁止修改);
  7. 甚至能夠經過 $store.dispatch() 來獲取其餘風格的樣式,並經過 $store.state$store.getters 來返回新風格的樣式;

四、總結

總而言之,假如你須要 數據組件 分離,分別處理,那麼使用 Vuex 是很是合適的。

相反,若是不須要分離處理,那麼不使用 Vuex 也不要緊。

好比某個數據只跟某組件打交道,是強耦合的。那麼這個數據就應該存放在該組件的 data 屬性中。

相關文章
相關標籤/搜索