在講解這些屬性之前,假如我們專案的目錄的結構如下:
### 目錄結構如下: 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>