当你的应用程序有一个非常大的状态对象时,通常会将其分成模块。
这基本上意味着将状态拆分成较小的部分。其中一个注意事项是,由于模块被集成到同一状态中,您不能使用相同的方法名称,例如:
moduleA {
actions:{
save(){}
}
}
moduleB {
actions:{
//this will throw an error that you have the same action defined twice
save(){}
}
}
因此,为了实现这一点,您可以选择将模块定义为命名空间,并且您可以在不同的模块中使用相同的方法:
moduleA {
actions:{
save(){}
},
namespaced: true
}
moduleB {
actions:{
save(){}
},
namespaced: true
}
然后你可以这样调用它:
this.$store.dispatch('moduleA/save')
this.$store.dispatch('moduleB/save')
请注意,如果您正在使用 mapGetter
或 mapActions
,事情可能会变得有点复杂,因为现在 getters 的形式为 ['moduleA/client']
因此,只有在确实需要时才使用它。
默认情况下,Vuex在全局命名空间中注册所有的getter、action。随着Vuex模块数量的增加,全局命名空间将面临冲突。因此,命名空间方法出现以解决这个问题。命名空间模块不会在全局命名空间中注册,而是在特定模块的namespace
下可用。
考虑一个具有两个模块products和cart的示例:
//products module
export default {
namespaced: true,
state: {
products: []
},
getters: {
products(state){
return state.products
}
},
actions: {
async load(context, params){ ... }
},
mutations: {
products(state, data){ ... }
}
}
另一个模块具有类似的 getters 和 actions 功能,
//cart module
export default {
namespaced: true,
state: {
products: [],
cart: []
},
getters: {
products(state){ return state.products }
cart(state){ return state.cart}
},
actions: {
async load(context, params){ ... },
async set(context, params){ ... },
},
mutations: {
products(state, data){ ... },
cart(state, data){ ... }
}
}
products
和cart
模块都有一个叫做product的getter和一个叫做load的action。如果没有使用命名空间,使用这样的模块会导致问题。在模块的根部设置namespaced:true
可以帮助解决这种情况。
您可以使用命名空间来映射getter,例如:...mapGetters(['products/products'])
,对于mapActions
也是如此。
...mapGetter('moduleA/client', {
a: state => state.a
});
我不是vue.js的专家,但从文档中可以看到,命名空间可用于修改模块的getter/action/mutation的路径访问。
默认情况下,namespaced: false
,所有的getter/action/mutation都可以被不同模块全局使用,因此如果要在不同模块中使用相同的getter/action/mutation,则必须将它们标记为namespaced: true
,否则会抛出错误。
另一个用途是将你的getter/action/mutation组织在不同的路径中(即模块注册的路径)。这在大型项目中非常有用,因为你可以立即知道getter/action/mutation定义在哪里,这样更容易找到它们。