当用Vue CLI 3初始化一个Vue的项目以后,关于Vuex的内容,默认是写在 src/store.js 文件中的。vue
因此,咱们能够对Vuex进行分层,使不一样的模块区分开来。es6
原目录是: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 // 存储一些变量的名字
复制代码
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');
}
}
}
复制代码
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: {
}
})
复制代码
在Home.vue组件中,去触发actions中的方法。
通常在actions里面,去请求后台接口。也就是说,把请求接口的方法,写在actions里面。而后在组件中去触发。
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>
复制代码
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>
复制代码
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>
复制代码
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>
复制代码