Vuex 4 — Modules Namespace
Tags: vue, webdev, programming, javascript
Published: 2021-01-26 01:22:30

**Check out my books on Amazon at https://www.amazon.com/John-Au-Yeung/e/B08FT5NT62**

**Subscribe to my email list now at http://jauyeung.net/subscribe/**


**Vuex 4 is in beta and it’s subject to change.**

Vuex is a popular state management library for Vue.

Vuex 4 is the version that’s made to work with Vue 3.

In this article, we’ll look at how to use Vuex 4 with Vue 3.

### Accessing Global Assets in Namespaced Modules

We can access global assets in namespaced modules.

For example, we can write:

```
<!DOCTYPE html>
<html lang="en">
  <head>
    <script src="https://unpkg.com/vue@next"></script>
    <script src="https://unpkg.com/vuex@4.0.0-beta.4/dist/vuex.global.js"></script>
    <title>App</title>
  </head>
  <body>
    <div id="app">
      <button @click="this['moduleA/increment']">increment</button>
      <p>{{this['moduleA/doubleCount']}}</p>
    </div>
    <script>
      const moduleA = {
        state: () => ({
          count: 0
        }),
        mutations: {
          increment(state) {
            state.count++;
          }
        },
        actions: {
          increment({ commit, dispatch }) {
            commit("increment");
            commit("someAction", null, { root: true });
          }
        },
        getters: {
          doubleCount(state) {
            return state.count * 2;
          }
        }
      };

      const store = new Vuex.Store({
        mutations: {
          someAction(state) {
            console.log("someAction");
          }
        },
        modules: {
          moduleA: {
            namespaced: true,
            ...moduleA
          }
        }
      });
      const app = Vue.createApp({
        methods: {
          ...Vuex.mapActions(["moduleA/increment"])
        },
        computed: {
          ...Vuex.mapGetters(["moduleA/doubleCount"])
        }
      });
      app.use(store);
      app.mount("#app");
    </script>
  </body>
</html>
```

We have the `increment` action that commits the `someAction` mutation from the root namespace.

Therefore, when we dispatch the `moduleA/increment` action, we should see `'someAction'` logged.

We called `commit` with an object with the `root: true` property to set make it dispatch the root mutation.

We can do the same with actions. For example, we can write:

```
<!DOCTYPE html>
<html lang="en">
  <head>
    <script src="https://unpkg.com/vue@next"></script>
    <script src="https://unpkg.com/vuex@4.0.0-beta.4/dist/vuex.global.js"></script>
    <title>App</title>
  </head>
  <body>
    <div id="app">
      <button @click="this['moduleA/increment']">increment</button>
      <p>{{this['moduleA/doubleCount']}}</p>
    </div>
    <script>
      const moduleA = {
        state: () => ({
          count: 0
        }),
        mutations: {
          increment(state) {
            state.count++;
          }
        },
        actions: {
          increment({ commit, dispatch }) {
            commit("increment");
            dispatch("someOtherAction", null, { root: true });
          }
        },
        getters: {
          doubleCount(state) {
            return state.count * 2;
          }
        }
      };

      const store = new Vuex.Store({
        mutations: {
          someAction(state) {
            console.log("someAction");
          }
        },
        actions: {
          someOtherAction({ commit }) {
            commit("someAction");
          }
        },
        modules: {
          moduleA: {
            namespaced: true,
            ...moduleA
          }
        }
      });
      const app = Vue.createApp({
        methods: {
          ...Vuex.mapActions(["moduleA/increment"])
        },
        computed: {
          ...Vuex.mapGetters(["moduleA/doubleCount"])
        }
      });
      app.use(store);
      app.mount("#app");
    </script>
  </body>
</html>
```

We called `dispatch` with an object with the `root: true` property to set make it dispatch the root action.

We can access root getters with the `rootGetters` property.

To do that, we write:

```
<!DOCTYPE html>
<html lang="en">
  <head>
    <script src="https://unpkg.com/vue@next"></script>
    <script src="https://unpkg.com/vuex@4.0.0-beta.4/dist/vuex.global.js"></script>
    <title>App</title>
  </head>
  <body>
    <div id="app">
      <button @click="this['moduleA/increment']">increment</button>
      <p>{{this['moduleA/doubleCount']}}</p>
    </div>
    <script>
      const moduleA = {
        state: () => ({
          count: 0
        }),
        mutations: {
          increment(state) {
            state.count++;
          }
        },
        actions: {
          increment({ commit, dispatch, rootGetters }) {
            console.log("increment", rootGetters.one);
            commit("increment");
          }
        },
        getters: {
          doubleCount(state, getters, rootState, rootGetters) {
            console.log("doubleCount", rootGetters.one);
            return state.count * 2;
          }
        }
      };

      const store = new Vuex.Store({
        getters: {
          one(state) {
            return 1;
          }
        },
        modules: {
          moduleA: {
            namespaced: true,
            ...moduleA
          }
        }
      });
      const app = Vue.createApp({
        methods: {
          ...Vuex.mapActions(["moduleA/increment"])
        },
        computed: {
          ...Vuex.mapGetters(["moduleA/doubleCount"])
        }
      });
      app.use(store);
      app.mount("#app");
    </script>
  </body>
</html>
```

We have a `one` root getter method in the store’s root.

Then we have the `rootGetters` property in the object parameter of the `increment` method.

We can get the getter’s return value with from the `rootGetters.one` property.

Other getters can get the value from the `rootGetters` parameter.

### Conclusion

We can namespace our store so that we divide our store into smaller chunks that have their own states.