由于使用单一状态树,应用的所有状态会集中到一个比较大的对象。当应用变得非常复杂时,store 对象就有可能变得相当臃肿。
为了解决以上问题,Vuex 允许我们将 store 分割成模块(module)。每个模块拥有自己的 state、mutation、action、getter、甚至是嵌套子模块——从上至下进行同样方式的分割:
Vuex配置文件 index.vue
import { createStore } from 'vuex'
const user = {
state: ()=> ({
name: "moneky",
slogen: "Hi Guys"
}),
mutations: {
setName(state, payload) {
state.name = payload;
}
},
actions: {},
getters: {
fullName(state) {
return state.name + state.slogen
},
//gettere是自身的getters,调用全局的getters,传rootGetters
fullName2(state, getters) {
return getters.fullName + " 2222"
},
}
}
export default createStore({
state: {
name: ""
},
mutations: {},
actions: {},
modules: {
user
}
})
Home.vue
<template>
<div class="home">
<h2>{{$store.state.user.name}}h2>
<h2>{{$store.state.user.slogen}}h2>
<h2>
<button @click="changeName('banner')">changeNamebutton>
h2>
<h2>{{$store.getters.fullName}}h2>
<h2>{{$store.getters.fullName2}}h2>
div>
template>
<script>
export default {
name: 'Home',
methods: {
changeName(value) {
this.$store.commit("setName", value)
}
}
}
script>
拥有模块时,查找state时,需添加相应的模块,如上方的例子,待用User模块里的name,写法如$store.state.user.name
, 而mutation里的方法则是直接调用,因为模块内部的 action、mutation 和 getter 是注册在全局命名空间的——这样使得多个模块能够对同一 mutation 或 action 作出响应。
若想要各个模块拥有不同的action、mutation 和 getter ,可以采用命名空间namespaced: true
如果你希望使用全局 state 和 getter,rootState 和 rootGetters 会作为第三和第四参数传入 getter,也会通过 context 对象的属性传入 action。
模块中调用全局的getters、state
index.js
import { createStore } from 'vuex'
const user = {
state: ()=> ({
name: "moneky",
slogen: "Hi"
}),
mutations: {
setName(state, payload) {
state.name = payload;
}
},
actions: {
dosome({commit,rootState,getters}) {
//还可dosome(context){} context里包含state、commit、rootSate等
console.log(rootState.num);
console.log(getters.fullName)
setTimeout(()=>{
//提交mutations方法
commit("setName", "hello vuex")
},2000)
}
},
getters: {
fullName(state) {
return state.name + state.slogen
},
fullName2(state, getters) {
return getters.fullName + " 2222"
},
fullName3(getters,rootState) {
return getters.fullName + rootState.num
}
}
}
export default createStore({
state: {
num: 5
},
getters: {
numPow(state) {
return state.num * state.num;
}
},
mutations: {
},
actions: {
},
modules: {
user,
}
})
Home.vue
<template>
<div class="home">
<h2>{{$store.state.user.name}}h2>
<h2>{{$store.state.user.slogen}}h2>
<h2>
<button @click="changeName('banner')">changeNamebutton>
h2>
<h2>{{$store.getters.fullName}}h2>
<h2>{{$store.getters.fullName2}}h2>
<h2>{{$store.getters.fullName3}}h2>
<h2>
<button @click="changeName2('banner22')">async changeNamebutton>
h2>
div>
template>
<script>
export default {
name: 'Home',
methods: {
changeName(value) {
this.$store.commit("setName", value)
},
changeName2(value) {
this.$store.dispatch("dosome",value)
}
}
}
script>
效果
点击async changeName按钮的效果
getters、mutations、action和模块可单独另写文件,用import从外部引入即可
import getters from “./getters.js”
import user from “./user.js”