DEV Community

Diego Rodriguez
Diego Rodriguez

Posted on

Vuex Module Communication Using Nuxt with Nuxt Property Decorators

When working with nuxt-property-decorators or specifically vuex-module-decorators I found that It was not clear how to make it work with Nuxt.

One thing that I could not figure out was how to call actions or mutations from inside modules. In this example I did a simple flow:

Component -> first module -> second module -> first module

First Module

The idea is that the component will get data from this module's state. And this module sets the data through a different module.

// ~/store/first.js import { Module, VuexModule, VuexMutation, VuexAction, } from 'nuxt-property-decorator' import { second } from '~/store' @Module({ name: 'first', namespaced: true, stateFactory: true, }) export default class First extends VuexModule { text = 'before update' @VuexMutation setText(val) { this.text = val } @VuexAction({ rawError: true }) setTextSecond(val) { second.setText(val) } } 

You can also dispatch an action from inside a module using namespaces. To do so, add a third parameter to the dispatch function with { root: true }

@VuexAction({ rawError: true }) setTextSecond(val) { this.context.dispatch('second/setText', val, { root: true }) } 

Note that I added an argument to VuexAction decorator. With { rawError: true } I get the real error if something goes wrong inside my action function. Otherwise it will throw a generic error that can be confusing.

Second Module

This module will set the first module's state by calling the mutation on that module.

// ~/store/second.js import { Module, VuexModule, VuexAction } from 'nuxt-property-decorator' import { first } from '~/store' @Module({ name: 'second', namespaced: true, stateFactory: true, }) export default class second extends VuexModule { @VuexAction({ rawError: true }) setText(val) { first.setText(val) } } 

Component

It works importing the store modules or by using the namespace

Using namespace

// ~/pages/storetest.vue <template> <div>text is: {{ text }}</div> </template> <script> import { Vue, Component } from 'nuxt-property-decorator' @Component export default class StoreTestComponent extends Vue { beforeMount() { this.$store.dispatch('first/setTextSecond', 'after update') } get text() { return this.$store.state.first.text } } </script> 

Using Module as Class

// ~/pages/storetest.vue <template> <v-container> <div>text is: {{ text }}</div> </v-container> </template> <script> import { Vue, Component } from 'nuxt-property-decorator' import { first } from '~/store' @Component export default class StoreTestComponent extends Vue { beforeMount() { first.setTextSecond('after update') } get text() { return first.text } } </script> 

Important note: Remember that you have to export the module for this method to work

// ~/utils/store-accessor.js import { getModule } from 'nuxt-property-decorator' import First from '~/store/first' import Second from '~/store/second' let first = null let second = null function initialiseStores(store) { first = getModule(First, store) second = getModule(Second, store) } export { initialiseStores, first, second, } 
// ~/store/index.js import { initialiseStores } from '~/utils/store-accessor' const initializer = (store) => initialiseStores(store) export const plugins = [initializer] export * from '~/utils/store-accessor' 

Top comments (0)