Vuex Module Communication Using Nuxt with Nuxt Property Decorators
Published on Aug 01, 2020 by Diego Rodriguez Mancini.
Introduction
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.
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.
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 stores or by using the namespace
Using namespace
<template> <v-container> <div>text is: {{ text }}</div> </v-container> </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
<template> <v-container> <div>text is: {{ text }}</div> </v-container> </template> <script> import { Vue, Component } from 'nuxt-property-decorator' import { first } from '~/store' import { second } 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 modules in store-accessor.js to make this method 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'