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)