16、状态模块化
为了合适分工,能够进行明确的个人状态管理
1、创建store模块
模块1
const state = { //创建状态存储
name:"product",
}
const mutations = { //创建状态修改函数
setName(store) {
store.name="product更改"
}
}
export default { //导出store模块配置
namespaced: true, //为模块添加命名空间,这样在外部可以根据map来映射模块方法属性
state,
mutations
}
模块2
const state = {
name:"study",
}
const mutations = {
setName(store) {
store.name="study更改"
}
}
export default {
state,
mutations
}
2、根模块进行模块的引入
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
import product from "./modules/product"; //引入状态模块
import study from "./modules/study";
export default new Vuex.Store({ //导出根模块
modules:{ //使用modules来合并多个模块
product,
study
}
state:{
myRoot:"index"
}
});
合并完的模块的各个属性(如store、mutations等),他们都是以属性的形式添加在了根组件相应的属性上,如
现在的根state与模块state进行合并后为
{
myRoot:"index",
product:{ //模块的state放在了根的state下面,相当于他的子state
name:"product",
},
study:{
name:"study",
},
}
这样的好处是,多个模块之间的store之间互不影响,分离开发,又能互相协作
3、组件中获取模块的状态与设置模块的状态
以store为例
1>通过$store去获取
我们已经知道模块store放置在根的store里面,并以各自模块名进行了区分我们可以直接进行获取
this.$store.state.product.name //获取product模块的name状态变量
this.$store._mutations.setName[0]() //获取setName方法并进行执行
像mutations与actions这样的方法,在进行模块引入时,并不是根据模块名去分类,而是根据方法名进行分类同一方法会放在一个数组里,这样出现同名方法会带来很麻烦的问题,
解决办法:为模块添加 namespaced:true启用他的命名空间,这样在方法名前面会添加 [模块名/方法名],避免了模块名重复的问题,以模块名为前缀避免了方法名的重复
2>通过map映射获取
map映射可以将模块的方法属性映射到组件的methods、computed等方法中,通过组件自身来进行调用
import { mapState,mapMutations } from "vuex"; //先引入相应的属性map方法
export default {
computed: { //通过计算属性来获取模块的store与getters
shadowHome() {
return this.$route.path === "/home/new";
},
...mapState('product',['name']) //为了与组件的私有计算属性共存,采用展开
},
methods: { // 通过methods来获取模块的mutitions与actions
...mapMutations('product',['setName'])
},
}
注意,这里的product之所以能够获取到模块store是因为设置了模块设置了 namespaced: true,该模块就成为命名空间模块了
这时候通过模块的指定方法、属性被放在了组件的methods、computed上我们通过this就可以进行访问
this.name //获取product模块的name变量
this.setName() //执行product模块的setName方法实现状态变更
映射的优点
将全局状态管理操作放在了组件内部进行,简化了操作
不需要进行事件的抛发,直接调用映射事件
映射的缺点
需要进行配置,设置命名空间
map语法
在引用模块方法并且模块设置命名控件时
在进行map映射属性方法后会在vue实例上创建一个同名的方法他指向的是,模块的方法,这样通过实例来调用模块的指定方法
methods: {
...mapMutations('product',['setName'])
},
他会去store根模块的_mutations对象下查找 product/setName方法,并以setName作为事件名映射到product/setName方法上
可以通过this.setName() 调用到store根模块的product/setName方法
在引用根模块方法时
methods: {
...mapMutations(['setName'])
},
去根模块下查找setName方法,并在vue实例上创建setName方法进行映射