對Vuex進行分層

當用Vue CLI 3初始化一個Vue的項目以後,關於Vuex的內容,默認是寫在 src/store.js 文件中的。vue

因此,咱們能夠對Vuex進行分層,使不一樣的模塊區分開來。es6

1.改造項目

原目錄是:vuex

src/store.js
複製代碼

更改後的目錄:api

src
    -- store
        -- modules
            -- cart.js         // 購物車
            -- product.js      // 商品列表
            -- xxx.js          // 其餘的,能夠是 user.js,用戶管理
        -- index.js            // 將原來的src/store.js移動到store目錄,並重命名爲 index.js
        -- mutation-types.js   // 存儲一些變量的名字
複製代碼

2.Vuex的modules 和 namespaced

namespaced是命名空間的意思。bash

先創建一些變量:函數

mutation-types.js:ui

// api的列表
export const GET_PRODUCT_LIST = 'GET_PRODUCT_LIST';  // 獲取商品列表
複製代碼

先編寫兩個模塊:this

cart.js:spa

// 爲了防止cart.js 和product.js 中的actions相互衝突,
// 須要引入一個命名空間的概念,這樣cart.js 和 product.js 中的都有用
export default {
    state: {
        carts:[]
    },
    actions: {
        
    }
}

複製代碼

product.js:code

import * as types from '../mutation-types';
export default {
    namespaced: true,
    state: {
        products: []
    },
    actions: {
        // [types.GET_PRODUCT_LIST]的意思是當前變量去取值
        // 至關於 getProductList(){}
        [types.GET_PRODUCT_LIST]({ commit}, payload){
            console.log('xxxx');
        }
    }
}
複製代碼

3.在 src/store/index.js

src/store/index.js:

import Vue from 'vue'
import Vuex from 'vuex'
import cart from './modules/cart'  // 引入其餘分層的模塊
import product from './modules/product'

Vue.use(Vuex)

export default new Vuex.Store({
    // 若是須要引入模塊中的狀態,須要用到 modules
    modules: {
        cart,
        product
    },
    state: {
        // xxx
    },
    mutations: {
        
    },
    actions: {
        
    }
})
複製代碼

4.在組件中觸發actions中的方法

在Home.vue組件中,去觸發actions中的方法。

通常在actions裏面,去請求後臺接口。也就是說,把請求接口的方法,寫在actions裏面。而後在組件中去觸發。

(1)第一種觸發actions的方式:使用this.$store.dispatch方法

Home.vue:

<template>
    <div class="home">
        商品頁
    </div>
</template>

<script>
import * as types from '../store/mutation-types'
export default {
    mounted(){
        // 1.第一種觸發actions的方式:使用this.$store.dispatch方法
        // 觸發actions
        // 'product/' + types.GET_PRODUCT_LIST是指定product.js模塊下的actions方法
        this.$store.dispatch('product/'+ types.GET_PRODUCT_LIST)
    }
}
</script>
複製代碼

(2) 第二種觸發actions的方式:使用 mapActions

Home.vue:

<template>
    <div class="home">
        商品頁
    </div>
</template>

<script>
import { mapActions } from 'vuex'
import * as types from '../store/mutation-types'
export default {
    methods: {
        // 'product' 指的是product.js 這個模塊
        // [type.GET_PRODUCT_LIST] 指的是變量取值
        ...mapActions('product', [types.GET_PRODUCT_LIST])
    },
    mounted(){
        // 2.第二種觸發actions的方式:使用 mapActions
        this[types.GET_PRODUCT_LIST]()
    }
}
</script>
複製代碼

(3)第三種方法:createNamespaceHelpers,建立命名空間的幫助方法

Home.vue:

<template>
    <div class="home">
        商品頁
    </div>
</template>

<script>
import { createNamespacedHelpers } from 'vuex'
let { mapActions }  = createNamespacedHelpers('product')  // 建立product的命名空間
import * as types from '../store/mutation-types'
export default {
    methods: {
        // 配合createNamespacedHelpers幫助方法使用
        // 已經指定命名空間,不須要在...mapActions()中指定
        ...mapActions([types.GET_PRODUCT_LIST])
    },
    mounted(){
        // 2.第二種觸發actions的方式:使用 mapActions
        this[types.GET_PRODUCT_LIST]()
    }
}
</script>
複製代碼

5.getters

getters,相似於computed

state和getters都屬於 Vuex的屬性。
好比,咱們要把state狀態的數據進行一次映射或者篩選,再把這個結果從新計算並提供組件使用。舉個例子:

store.js:

state: {
     arr: [
       {id: 1, name: 'iissoft',score: 80},
       {id: 2, name: 'steven', score:60},
       {id: 3, name: 'jerry', score:90}
     ]
},
getters: {
    arrList: function (state) { //這裏咱們對狀態進行映射,進行從新計算
         return state.arr.map(function(item){
               return item.score >= 60 ? '及格' : '不及格';
         })
    }
}
複製代碼

此時,getters會暴露一個store.getters 對象,咱們就能夠在任何組件中使用 this.$store.getters.xxx來綁定數據。

在組件中調取getters中的數據。 header.vue:

<template>
     <div>
          <ul>
              <li v-for="item in arrList">{{item}}</li>
          </ul>
     </div>
</template>
<script>
     export default {
         computed: {
	      arrList: function (){
                     return this.$store.getters.arrList;  //經過store.getters對象來訪問
              }
         }
     }
</script>
複製代碼

另外一種方式,來調取getters中的數據。

Vuex給咱們提供了另外一個方法mapGetters。

store.js:

state: {
    arr: [  //狀態
        {id: 1, name: 'iissoft', score: 80 },
        {id: 2, name: 'steven', score: 60},
        {id: 3, name: 'jerry', score: 90}
    ]
},
getters: {  //這裏咱們使用es6新語法箭頭函數
    arrList: state => state.arr.map(item => item.score >= 60 ? '及格':'不及格')
}
複製代碼

在組件中使用 mapGetters來調取 getters中的數據。

結合 ...對象運算符來合併咱們組件的本地計算屬性。

header.vue:

<template>
    <div>
        <ul>
            <li v-for="item in arrList">{{item}}</li>
        </ul>
    </div>
</template>
<script>
    import { mapGetters } from 'vuex'
    export default {
        computed: {
            ...mapGetters(['arrList'])
        }
    }
</script> 
複製代碼

最後若是咱們想給getters屬性起個別名,咱們能夠經過對象的形式:

<template>
    <div>
        <ul>
            <li v-for="item in newArr">{{item}}</li>
        </ul>
    </div>
</template>
<script>
import { mapGetters } from 'vuex'
export default {
    computed: {
        ...mapGetters({
            newArr: 'arrList'  //給getters屬性arrList起個別名newArr
        })
    }
}
</script>
複製代碼
相關文章
相關標籤/搜索