---
# System prepended metadata

title: '[Vuex] 基礎介紹'
tags: [Vue.js]

---

# [Vuex] 基礎介紹
###### tags: `Vue.js`

## vue元件階層處理方式

* 父子階層可透過emit及props做傳遞
![](https://i.imgur.com/eWcb5Kr.png)
* 如非父子層的關係，同階層就得經由eventbus傳遞，不過僅適合在較輕量的專案，因過多易混亂難以管理
* 也能選擇全域變數，但資料無法資料綁定
![](https://i.imgur.com/ZyoHVbi.png)

於是vuex就是為了解決元件層級傳遞的複雜性而被開發出，不論在層級位置都能互相傳遞，也能有雙向綁定的特性
![](https://i.imgur.com/Xn2e3aq.png)

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

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




## vuex環境架構

![](https://i.imgur.com/ubvsqZ6.png)
![](https://i.imgur.com/VueGkLE.png)






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參數。

# 補充：

1. * 下方案例actions是負責處理函式的部份，函式會帶兩個數值context以及status，context只是單純預設，就如同mutations裡的state一樣，單純是actions及mutation裡的小工人，而status才是帶入的參數。
1. * muations前面有說就是將actions執行的函式結果，經由muations匯入state的變數資料裡

1. * 在執行前面的步驟時，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,
  },
```
2. 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']),`

範例如下：
![](https://i.imgur.com/0tYC1JI.png)


## 多模組使用概念

執行步驟

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


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

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

```
2. 母模組底部新增modules以連結子模組

```
modules:{
    productsModel,
  }
```
3. 新增子模組即可，同樣依照需求導入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開啟後為“區域變數”
![](https://i.imgur.com/NuCvqMY.png)

新增root將此段語法變更環境為全域
![](https://i.imgur.com/SshZHPf.png)



