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

我最近开始使用vuex

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

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

非常感谢。

【问题讨论】:

    标签: javascript vue.js vuex


    【解决方案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 的定义位置,从而更容易找到它们。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2020-03-29
            • 2020-09-27
            • 2016-03-11
            • 2021-05-17
            • 2020-05-07
            • 2020-07-14
            • 2023-03-19
            • 2018-11-16
            相关资源
            最近更新 更多