Nuxt + Vuex - How do I break down a Vuex module into separate files?
In nuxt version 2.14^ you don't necessary have to create this in your store root index.js file.
import Vuex from 'vuex';
import apiModule from './modules/api-logic';
import appModule from './modules/app-logic';
const createStore = () => {
return new Vuex.Store({
namespaced: true,
modules: {
appLogic: appModule,
api: apiModule
}
});
};
export default createStore
But instead, you can just leave your root index.js file as default or do what you need. No need to import.
store/index.js
export const state = () => ({
counter: 0
})
export const mutations = {
increment(state) {
state.counter++
}
}
export const actions = {
async nuxtServerInit({ state, commit }, { req }) {
const cookies = this.$cookies.getAll()
...
}
And this how it looks like, its very simple.
Folder structure
ð¦store
┣ ðauth
┣ ðutils
┣ ðposts
┃ ┗ ðactions.js
┃ ┗ ðmutations.js
┃ ┗ ðgetters.js
┃ ┗ ðindex.js
┣ index.js
Example
store/posts/index.js
you can just put the state function. You don't need to import the actions, getters and mutations.
export const state = () => ({
comments: []
})
store/posts/actions.js
const actions = {
async getPosts({ commit, state }, obj) {
return new Promise((resolve, reject) => {
...
}
}
}
export default actions
store/posts/mutations.js
const mutations = {
CLEAR_POST_IMAGE_CONTENT: (state) => {
state.post_image_content = []
}
}
export default mutations
store/posts/getters.js
const getters = {
datatest: (state) => state.datatest,
headlineFeatures: (state) => state.headlineFeatures,
}
export default getters
The effect is same as @CMarzin answer but much cleaner
I am using nuxt 2.1.0
If you want to have something like this :
In my store/index.js
Make sure you have namespaced: true
import Vuex from 'vuex';
import apiModule from './modules/api-logic';
import appModule from './modules/app-logic';
const createStore = () => {
return new Vuex.Store({
namespaced: true,
modules: {
appLogic: appModule,
api: apiModule
}
});
};
export default createStore
In moduleOne
In my store/api-logic/index.js
import actions from './actions';
import getters from './getters';
import mutations from './mutations';
const defaultState = {
hello: 'salut I am module api'
}
const inBrowser = typeof window !== 'undefined';
// if in browser, use pre-fetched state injected by SSR
const state = (inBrowser && window.__INITIAL_STATE__) ? window.__INITIAL_STATE__.page : defaultState;
export default {
state,
actions,
mutations,
getters
}
In my store/api-logic/getters.js
export default {
getHelloThere: state => state.hello
}
In module Two
In my store/app-logic/index.js
import actions from './actions';
import getters from './getters';
import mutations from './mutations';
const defaultState = {
appLogicData: 'bonjours I am module Logic'
}
const inBrowser = typeof window !== 'undefined';
// if in browser, use pre-fetched state injected by SSR
const state = (inBrowser && window.__INITIAL_STATE__) ? window.__INITIAL_STATE__.page : defaultState;
export default {
state,
actions,
mutations,
getters
}
In my store/app-logic/getters.js
export default {
getAppLogicData: state => state.appLogicData
}
Anywhere in the app
computed: {
...mapGetters({
logicData: 'getAppLogicData',
coucou: 'getHelloThere'
})
},
mounted () {
console.log('coucou', this.coucou) --> salut I am module api
console.log('logicData', this.logicData) --> bonjours I am module Logic
}
Bonus Point
If you want to communicate between the modules for example a action in app-logic which trigger something in api-logic. So app-logic (module one) to api-logic (module two)
When you specify root: true
it will start to look at the root of the store.
In store/app-logic/actions.js
callPokemonFromAppLogic: ({ dispatch }, id) => {
dispatch('callThePokemonFromApiLogic', id, {root:true});
},
In store/api-logic/actions.js
callThePokemonFromApiLogic: ({ commit }, id) => {
console.log('I make the call here')
axios.get('http://pokeapi.salestock.net/api/v2/pokemon/' + id).then(response => commit('update_pokemon', response.data))
},
In store/api-logic/index.js
add another entry
import actions from './actions';
import getters from './getters';
import mutations from './mutations';
const defaultState = {
appLogicData: 'bonjours I am module Logic',
pokemon: {}
}
const inBrowser = typeof window !== 'undefined';
// if in browser, use pre-fetched state injected by SSR
const state = (inBrowser && window.__INITIAL_STATE__) ? window.__INITIAL_STATE__.page : defaultState;
export default {
state,
actions,
mutations,
getters
}
In store/api-logic/mutations.js
add the pokemon mutation :p
update_pokemon: (state, pokemon) => {
state.pokemon = pokemon
}
Anywhere in the app :
computed: {
...mapGetters({
bidule: 'bidule',
pokemon: 'getPokemon'
})
},
mounted() {
console.log('bidule', this.bidule)
this.callPokemonFromAppLogic('1') --> the call
console.log('the pokemon', this.pokemon.name) --> 'bulbasaur'
},
methods: {
...mapActions({
callPokemonFromAppLogic: 'callPokemonFromAppLogic'
}),
}
At the end your Vue devTool should look like this :)
And Voilà I hope It was clear. Code example :
https://github.com/CMarzin/nuxt-vuex-modules