理解Vuex的輔助函式mapState, mapActions, mapMutations用法

龍恩0707發表於2018-10-15

在講解這些屬性之前,假如我們專案的目錄的結構如下:

### 目錄結構如下:
demo1                                       # 工程名
|   |--- dist                               # 打包後生成的目錄檔案             
|   |--- node_modules                       # 所有的依賴包
|   |--- app
|   | |---index
|   | | |-- views                           # 存放所有vue頁面檔案
|   | | | |-- parent.vue                    # 父元件
|   | | | |-- child.vue                     # 子元件
|   | | | |-- index.vue
|   | | |-- components                      # 存放vue公用的元件
|   | | |-- js                              # 存放js檔案的
|   | | |-- store                           # store倉庫
|   | | | |--- actions.js
|   | | | |--- mutations.js
|   | | | |--- state.js
|   | | | |--- mutations-types.js
|   | | | |--- index.js
|   | | |-- app.js                          # vue入口配置檔案
|   | | |-- router.js                       # 路由配置檔案
|   |--- views
|   | |-- index.html                        # html檔案
|   |--- webpack.config.js                  # webpack配置檔案 
|   |--- .gitignore  
|   |--- README.md
|   |--- package.json
|   |--- .babelrc                           # babel轉碼檔案

具體理解vuex的專案構建可以看這篇文章(https://www.cnblogs.com/tugenhua0707/p/9763177.html). 下面講解的也是在這篇文章專案結構基礎之上進行講解的。當然如果你對 vuex熟悉的話,就不用看了,直接跳過即可。

注意:下面的程式碼都是在 webpack+vue+route+vuex 中構建的,可以把下面的程式碼 複製到該專案中執行即可。

一:理解mapState的使用

當我們的元件需要獲取多個狀態的時候,將這些狀態都宣告為計算屬性會有些重複和冗餘,為了解決這個問題,我們可以使用mapState的輔助函式來幫助我們生成計算屬性。

mapState函式返回的是一個物件,我們需要使用一個工具函式將多個物件合併為一個,這樣就可以使我們將最終物件傳給computed屬性。

上面的表述可能會有些模糊,下面我們來做個簡單的demo來演示一下:

專案架構如上面示意圖所示,先看看 app/index/store/state.js 程式碼如下:

export default {
  add: 0,
  errors: '',
  counts: 0
};

app/index/store/mutations.js 程式碼如下:

import * as types from './mutations-types';

export default {
  [types.ADD] (state, payload) {
    state.add = payload;
  },
  [types.SETERROR] (state, payload) {
    state.errors = payload;
  },

  [types.COUNTASYNC] (state, payload) {
    state.counts = payload;
  }
}

app/index/store/mutations-types.js 程式碼如下:

// 新增list
export const ADD = 'ADD'; 

// 設定錯誤提示
export const SETERROR = 'SETERROR';

// 非同步操作count
export const COUNTASYNC = 'COUNTASYNC';

app/index/store/index.js 程式碼如下:

import Vue from 'vue';
import Vuex from 'vuex';

import state from './state';
import mutations from './mutations';
import actions from './actions';

Vue.use(Vuex);

Vue.config.devtools = true;

export default new Vuex.Store({
  state,
  mutations,
  actions
});

app/index/store/actions.js 程式碼請看github

如上程式碼所示,現在我們在 app/index/views/parent.vue 這個路由下,在mounted生命週期列印一下 console.log(this);這句程式碼的時候,如下程式碼:

<template>
  <div></div>
</template>
<script type="text/javascript">
  export default {
    data() {
      return {
        
      }
    },
    methods: {
      
    },
    mounted() {
      console.log(this);
    }
  }
</script>

在瀏覽器執行後,如下圖所示:

如果我們想獲取add,或 count的時候,我們需要使用 this.$store.state.add 或 this.$store.state.count 這樣的。

現在我們使用 mapState的話,程式碼就變成如下了:

<template>
  <div>
    
  </div>
</template>
<script type="text/javascript">
  import { mapState } from 'vuex';
  export default {
    data() {
      return {
        
      }
    },
    methods: {
      
    },
    computed: {
        ...mapState({
          add: state => state.add,
          counts: state => state.counts
        })
    },
    mounted() {
      console.log(this.add); // 列印出 0
      console.log(this.counts); // 列印 0 
    }
  }
</script>

如上程式碼,我們使用 mapState工具函式會將store中的state對映到區域性計算屬性中。
我們在mounted方法內,直接使用 this.xx 即可使用到對應computed中對應的屬性了。也就是 我們使用 this.add 就直接對映到 this.$store.state.add 了 。

當然mapState也可以接受一個陣列,如下簡單程式碼:

computed: {
  /*
  ...mapState({
    add: state => state.add,
    counts: state => state.counts
  })
  */
  ...mapState([
    'add',
    'counts'
  ])
},
mounted() {
  console.log(this);
}

然後我們再在控制檯檢視輸出的this的值,如下:

可以看到,接受陣列也是可以的,在mounted生命週期內,我們直接可以使用 this.add 或 this.counts 可以獲取到值了。

切記:mapState的屬性的時候,一定要和state的屬性值相對應,也就是說 state中定義的屬性值叫add,那麼mapState就叫add,如果我們改成add2的話,就獲取不到add的值了,並且add2的值也是 undefined,如下所示:

二:理解mapActions的使用
mapActions 的思想 和 mapState 一樣的,下面我們直接看程式碼的使用方法哦,如下程式碼:

如果我們不使用 mapActions 的話,我們呼叫某個方法需要如下程式碼所示:

<template>
  <div></div>
</template>
<script type="text/javascript">
  export default {
    data() {
      return {
        
      }
    },
    created() {
      this.test();
    },
    methods: {
      test() {
        // 呼叫action 需要時使用 this.$store.dispatch 這樣的
        Promise.all([this.$store.dispatch('commonActionGet', ['getPower', {}])]).then((res) =>{
          
        });
      }
    },
    computed: {

    },
    mounted() {
      
    }
  }
</script>

下面我們使用 mapActions的話,程式碼如下所示:

<template>
  <div>  
  </div>
</template>
<script type="text/javascript">
  import { mapActions } from 'vuex';
  export default {
    data() {
      return {
        
      }
    },
    created() {
      this.test();
    },
    methods: {
      test() {
        // 呼叫
        Promise.all([this.commonActionGet(['getPower', {}])]).then((res) => {

        });
      },
      // mapActions 使用方法一 將 this.commonActionGet() 對映為 this.$store.dispatch('commonActionGet')
      ...mapActions(['commonActionGet', 'commonActionGetJSON', 'commonActionPost', 'commonActionPostJSON'])
      /*
       // 第二種方式
       ...mapActions({
         'commonActionGet': 'commonActionGet',
         'commonActionGetJSON': 'commonActionGetJSON',
         'commonActionPost': 'commonActionPost',
         'commonActionPostJSON': 'commonActionPostJSON'
       })
      */
    }
  }
</script>

三:理解 mapMutations 的使用。

首先我們不使用 mapMutations的話,呼叫mutations裡面的方法,是如下程式碼:

<template>
  <div>  
  </div>
</template>
<script type="text/javascript">
  export default {
    data() {
      return {
        
      }
    },
    created() {
      this.test();
    },
    methods: {
      test() {
        // 呼叫Mutations 需要時使用 this.$store.commit('ADD', 1) 這樣的
        Promise.all([this.$store.commit('ADD', 1)]).then(() =>{
          console.log(this);
        });
      }
    }
  }
</script>

列印 如上 this程式碼後,看到如下圖所示:

想獲取值,使用 this.$store.state.add 就等於1了。

下面我們使用 mapMutations話,程式碼需要改成如下程式碼:

<template>
  <div>
  </div>
</template>
<script type="text/javascript">
  import { mapMutations } from 'vuex';
  export default {
    data() {
      return {
        
      }
    },
    created() {
      this.test();
    },
    methods: {
      test() {
        // 使用 mapMutations 呼叫方式如下:
        Promise.all([this.ADD(1)]).then(() => {
          console.log(this);
        });
      },
      /*
      // mapMutations 使用方法1
      ...mapMutations(['ADD']), // 會將 this.ADD 對映成 this.$store.commit('ADD') 
      */
      // mapMutations 使用方法2
      ...mapMutations({
        'ADD': 'ADD'
      })
    }
  }
</script>

 

相關文章