vuex中模块的命名空间到底是啥

Posted

技术标签:

【中文标题】vuex中模块的命名空间到底是啥【英文标题】:What exactly is namespacing of modules in vuexvuex中模块的命名空间到底是什么 【发布时间】:2018-05-27 07:04:49 【问题描述】:

我最近开始使用vuex

官方docs很好地解释了modules是什么,但我不确定我是否理解了modules中的namespaces

谁能以更好的方式对命名空间有所了解? 何时/为什么使用它?

非常感谢。

【问题讨论】:

【参考方案1】:

当你有一个很大的应用程序有一个非常大的状态对象时,你经常会把它分成modules。

这基本上意味着您将状态分解为更小的部分。需要注意的一点是,您不能为模块使用相同的方法名称,因为它已集成到相同的状态中,例如:

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')

请注意,如果您使用 mapGettermapActions,这可能会使事情变得有点复杂,因为 getter 现在采用 ['moduleA/client'] 的形式

所以只有当你真的需要时才使用它。

【讨论】:

【参考方案2】:

要使用它,我们可以将模块命名空间字符串作为第一个参数传递给帮助程序,以便使用该模块作为上下文完成所有绑定。以上可以简化为:

...mapGetter('moduleA/client', 
    a: state => state.a
);

【讨论】:

【参考方案3】:

默认情况下,Vuex 会在 全局命名空间 中注册所有 getteractions。随着 Vuex 模块的大量增长,全局 Vuex 命名空间将面临冲突。命名空间方法用于解决此问题。命名空间模块不会在全局命名空间中注册。相反,它在特定模块 namespace 下可用。

考虑具有两个模块产品和购物车的示例,

//products module
export default 
    namespaced: true,
    state: 
        products: []
    ,
    getters: 
        products(state)
            return state.products
        
    ,
    actions: 
        async load(context, params) ... 
    ,
    mutations: 
        products(state, data) ... 
    

和另一个具有类似 getter 和操作的模块,

//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) ... 
    

productscart 模块都有一个共同的 getter product 和 action load。如果您在没有命名空间的情况下使用此类模块,则会产生问题。这里在模块的根目录中设置namespaced: true有助于恢复这种情况。

您可以使用命名空间将 getter 映射为 ...mapGetters(['products/products']),同样适用于 mapActions

【讨论】:

【参考方案4】:

我不是 vue.js 方面的专家,但正如我在文档中看到的,命名空间可用于修改对模块的 getters/actions/mutations 的路径访问。

默认情况下namespaced: false所有的getter、action、mutation都可以被不同的模块全局使用,所以如果你想在不同的模块中使用相同的getter/action/mutation,你必须将它们标记为namespaced: true,否则会抛出错误。

它的另一个用途是在不同的路径(模块注册的路径)中组织你的 getter/actions/mutations。这在大型项目中非常有用,因为您可以立即知道 getter/action/mutation 的定义位置,从而更容易找到它们。

【讨论】:

以上是关于vuex中模块的命名空间到底是啥的主要内容,如果未能解决你的问题,请参考以下文章

vuex中module的命名空间概念

vuex 模块还需要命名空间吗?

如何在模块命名空间中使用 Vuex 类型常量?

如何为 vuex 命名空间模块状态创建 getter 和 setter

具有多个模块的 vuex 命名空间 mapState

Vuex,命名空间的模块获取器在根获取器中不可用?