Try   HackMD

[Vuex] 基礎介紹

tags: Vue.js

vue元件階層處理方式

  • 父子階層可透過emit及props做傳遞
    Image Not Showing Possible Reasons
    • The image file may be corrupted
    • The server hosting the image is unavailable
    • The image path is incorrect
    • The image format is not supported
    Learn More →
  • 如非父子層的關係,同階層就得經由eventbus傳遞,不過僅適合在較輕量的專案,因過多易混亂難以管理
  • 也能選擇全域變數,但資料無法資料綁定
    Image Not Showing Possible Reasons
    • The image file may be corrupted
    • The server hosting the image is unavailable
    • The image path is incorrect
    • The image format is not supported
    Learn More →

於是vuex就是為了解決元件層級傳遞的複雜性而被開發出,不論在層級位置都能互相傳遞,也能有雙向綁定的特性

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

總結使用時機

回想頁籤的元件製作,當需要父層的變數值(props取得),也需要呼叫父層的函式(emit呼叫),利用上述兩種方式就可以進行父層子層的溝通。

而在Vuex裡操作能輕鬆的減輕複雜度,把Vuex想像一個雲端空間,裡頭放著很多Methods以及data變數資料,當有任何元件需要時,無論是取變數值、函式,都可以與vuex進行溝通取值(computed裡用mapGetter),或呼叫函式(用dispatch)取得資料,可以說是把所有的運算都放在Vuex進行集中式管理。

vuex環境架構

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

actions是指狀態的改變就像是methods的函式,當state的變數需要做更動時,actions是無法直接變更的,需經由代理商mutation當作兩者的媒介。

案例:我們可以看到state跟actions裡的資料完全沒有一點瓜格,都是透過mutations來連結彼此,逐一解釋三者關聯,

  • 在mutations裡先命名LOADING為此橋樑的名稱,參數裡載入兩個位置(state預設, actions參數),以此將兩者串連。
  • actions也要先命名函式名稱updateLoading,並增加兩個參數,前者是函式內使用的變數,第二則成為payload是傳入mutation裡的參數,內容我們先宣告變數名稱要串連mutations的橋樑名稱,以及順帶將payload參數也傳入即可完成
  • 執行流程:html裡寫入vm.$store.dispatch('updateLoading', true),內容主要是呼叫action函式名,並且載入參數true,這時action函式就會進行動作,傳入mutations執行並改變state裡的值,也就是status參數。

補充:

    • 下方案例actions是負責處理函式的部份,函式會帶兩個數值context以及status,context只是單純預設,就如同mutations裡的state一樣,單純是actions及mutation裡的小工人,而status才是帶入的參數。
    • muations前面有說就是將actions執行的函式結果,經由muations匯入state的變數資料裡
    • 在執行前面的步驟時,mutations要先命名一個名稱(建議大寫),讓actions知道要匯入哪一個mutations的項目裡。
export default new Vuex.Store({
  state: {
    isLoading: false,
  },
  //操作行為
  actions:{
    updateLoading(context, status) {
        context.commit('LOADING', status);
      },
  },
  //操作狀態
  mutations:{
    LOADING(state, status) { //第二個參數是外部傳入
        state.isLoading = status;
      },

  }
});

主頁面使用dispatch將需求傳至action裡,並帶指定參數

 vm.$store.dispatch('updateLoading', true);

如果有要回傳變數,則新增computed裡當作state的接口

 computed: {
    cart() {
      return this.$store.state.cart;
    },

基本新增項目

  1. index.js上新增action + mutations + state
  2. vue頁面新增method(dispatch)+ computed

補充computed主要是與state變數當作接口

getters用法

目的:新增getter是為了簡潔vue頁面裡的程式碼,將需要匯集的攏長的程式碼寫在index.js裡

  1. 在index.js上新增getters
 getters: {
    categories: state => state.categories,
  },
  1. vue頁面的script下新增import vuex物件,再到computed位置刪除既有的語法刪除,更改成mapGetters

script下新增

import { mapGetters} from 'vuex';

computed刪除既有的,再寫入mapgetters載入需回傳的變數(可新增多組)。

...mapGetters(['categories', 'products']),

mapAction語法

呼叫action函式,可以使用mapAction取代dispatch,也是為了簡潔頁面,增加統一管理性,但如果是要帶參數就不可以使用此語法。

使用mapAction語法,需在script下新增

import { mapGetters, mapActions } from 'vuex';

並在method裡的呼叫語法裡刪除既有的dispatch語法直接改成mapAction支援的格式
...mapActions(['getProducts']),

範例如下:

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

多模組使用概念

執行步驟

新增另一組B模組分類完後,在主模組A要import載入B模組,並在模組A下方新增modules模組載入B模組的名稱即可順利啟用。也就是說模組也是有分父子層,父層仍是匯集地,子層仍要匯入父層才可以使用。

將index.js指令做模組分類,例如:取得商品、前後台

方法

  1. 在母模組js裡新增
import productsModel from './products';

  1. 母模組底部新增modules以連結子模組
modules:{
    productsModel,
  }
  1. 新增子模組即可,同樣依照需求導入axios工具

將子模組的函數歸納成區域變數

觀念

預設state是區域變數 / mutation,gutter,actions是全域變數,如有需要宣告或更改就需要調整,因為當全域的狀況下,呼叫action如有相同名稱就會產生錯亂,因此我們可以改成區域變數解決

  • 狀況一

因此有一個頁面(是使用子模組)要取用母模組的state變數時,需要寫入modules模組的名稱,例如:this.$store.state.productsModules模組名稱.producs變數名稱

  • 狀況二

要將mutation,gutter,actions更改為區域變數,需在母模組新增一行 namespaced : true

  • 狀況三

是狀況二的延伸,當有很多組模組時actions函式命名很容易重複,因此使用區域變數是個解決辦法,如此一來在不同模組內相同的函式名稱是可以被接受的,但在啟用函式時,就必須在前面新增B模組名稱當做宣告,例如:mapGetters('productsModules',['products', 'categories'])

  • 觀念結論:

模組主要目的是匯集元件的,但很容易過多的函式指令導致非常混亂,因此模組自身也需要分類,分類後的子模組也需要載入母模組裡的modules裡,也由於是不同位置,因此取用時仍要注意區域、全域變數,在啟用或改變狀態時,都需要依照上方狀況調整,會是比較難操作的部分。

新增namespaced開啟後為“區域變數”

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

新增root將此段語法變更環境為全域

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →