namespaced 命名空间
引用两位大佬的解释
1、默认情况下,模块内部的 action、mutation 和 getter 是注册在全局命名空间的,这样使得多个模块能够对同一 mutation 或 action 作出响应。如果希望你的模块具有更高的封装度和复用性。
2、vuex中的store分模块管理,需要在store的index.js中引入各个模块,为了解决不同模块命名冲突的问题,将不同模块的namespaced:true,之后在不同页面中引入getter、actions、mutations时,需要加上所属的模块名
举个例子
类似于发布订阅机制,多个模块的同名方法会放在同一个数组中,在对根store进行dispatch、commit抛发事件时,会执行这一个事件对应数组里的所有函数,也就是所有的模块都会执行同名函数,有时候想要针对某个模块进行事件的抛发,这个时候为每个同名方法添加模块的前缀就能解决这个问题了
namespaced:true 就会自动的在方法名前面添加模块名来进行方法区分
const state = { //创建状态存储
name:"product",
}
const mutations = { //创建状态修改函数
setName(store) {
store.name="product更改"
}
}
export default { //导出store模块配置
namespaced: true, //为模块添加命名空间,这样在外部可以根据map来映射模块方法属性
state,
mutations
}
组件中map引用
methods: { // 通过methods来获取模块的mutitions与actions
...mapMutations('product',['setName']) // 为setName上追加/product,最终查找的是 /product/setName方法
},
这个方法在模块设置了namespaced: true后就已经在根store的_mutations中进行了重命名为/product/setName ,所以可以正确的查找到
原理
namespaced: true;
模块在导出时加上这个属性开启了命名空间,这样这个模块的所有方法都会在前面加上模块名前缀,同时在模块进行commit、dispatch操作来抛发事件也会在前面补上模块前缀,如
文件名product.js
const state = {
name: "product",
}
const mutations = {
setName(store) { //在全局引入后方法名为 'product/setName'
store.name = "product更改";
console.log("produtaaa")
}
}
const actions = {
subNameToStudy({ commit }, payLoad) { //在全局引入后方法名为 'product/subNameToStudy'
commit("study/setName", "新名字", { //在进行提交时类型为 'product/study/setName'
root: true
});
commit("setName", "新名字", { //在进行提交时类型为 'product/setName'
root: true
});
}
}
export default {
state,
mutations,
actions,
namespaced: true
}
模块在根模块进行引入后就合并在了根模块的方法集中(_mutations、_actions),这样进行commit、dispatch时也是在向根模块进行事件的提交与抛发
由此可以看到,在设置namespaced: true后的模块无论进行什么操作都会去查找自身模块中的方法,在commit提交product/setName事件,而导出时的setName事件正好变为product/setName这样完美的进行了事件在本模块的抛发并且不会影响其他模块
通过命名空间与actions来进行store模块之间的事件抛发
有这样的一种情况,在两个独立的模块中要进行某些数据的交互,需要进行事件的抛发但是设置命名空间后再actions进行commit与dispatch时会自动在前面添加当前模块的前缀,强制模块向自身抛发事件,做不到向另一个具有命名空间的模块进行抛发,这时候要想办法在抛发时将命名空间的自动添加前缀去掉
在actions方法的commit与dispatch方法中第三个参数具有阻止添加前缀的功能{root:true},他的意思是向根模块进行抛发,既然不是向本模块抛发命名空间会判定不加前缀
抛发事件的store模块(projuct.js)
const actions = {
subNameToStudy({ commit }, payLoad) {
commit("study/setName", "新名字", { //由于添加了root:true ,在进行commit与dispatch时不再添加'projuct/'前缀
root: true
})
}
}
export default {
state,
mutations,
actions,
namespaced: true,
}
subNameToStudy方法中的commit向根模块抛发了一个 study/setName 事件,顾名思义我们希望找到的是具有命名空间的study模块中的setName方法
接收事件的store模块(study.js)
const state = {
name:"study",
age:0
}
const mutations = {
setName({name},payLoad) { //在进行跟模块引入时放在变为 study/setName方法名,存储在根模块的_mutations中
name="study更改";
console.log(payLoad,"aa")
},
setAge({age}){
age=20
}
}
export default {
state,
mutations,
namespaced: true
}
在subNameToStudy抛发事件后study模块接受到了study/setName执行了setName方法 最终打印 ‘新名字 aa’
store模块间的数据交互就完成了