对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>
复制代码
相关文章
相关标签/搜索