Access state from another module in Nuxt

No doubt, Vue.js is a great framework for building amazing User Interface on the web. Currently ahead of React in numbers of GitHub stars.

Vue Shinning

I have been basking in the euphoria of working with Vue, but having tinkered with Nuxt lately, the experience is taken to a whole new level.

Setting up your Vue app to be server rendered could be a challenging task, especially for newbies. That is what Nuxt has in its belt among many other benefits like nice project structure, automatic code splitting, easy compilation of ES6/ES7, and great community etc. 

Basically, Nuxt is a framework on top of Vue to simplify Universal or Single Page Vue applications.

Single State Tree versus Modular style

According to Vuex Documentation: 

Vuex uses a single state tree - that is, this single object contains all your application level state and serves as the "single source of truth". This also means usually you will have only one store for each application. A single state tree makes it straightforward to locate a specific piece of state, and allows us to easily take snapshots of the current app state for debugging purposes.

Using this style, all the states of your application is contained in one object. This is could be messy and overwhelming in big projects.

However, Vuex allows us to use modules to divide our store. Hence, each module can have its own state, mutations, actions, getters and nested modules too.

​
const moduleA = {
  state: { ... },
  mutations: { ... },
  actions: { ... },
  getters: { ... }
}

const moduleB = {
  state: { ... },
  mutations: { ... },
  actions: { ... }
}

const store = new Vuex.Store({
  modules: {
    a: moduleA,
    b: moduleB
  }
})

store.state.a // -> `moduleA`'s state
store.state.b // -> `moduleB`'s state

​

Doing it the Nuxt way

Nuxt, basically, have two ways of setting up store: Classic and Modules.

Classic: store/index.js returns a store instance.

import Vuex from 'vuex'

const createStore = () => {
  return new Vuex.Store({
    state: {
      counter: 0
    },
    mutations: {
      increment (state) {
        state.counter++
      }
    }
  })
}

export default createStore

Modules: Every file inside the store directory is a module.

If you want this option, export the state as a function, and the mutations and actions as objects in store/index.js instead of a store instance.

​​​​export const state = () => ({
  counter: 0
})

export const mutations = {
  increment (state) {
    state.counter++
  }
}

The Challenge

Having set your store using module option, the ideal place to access state from another module is in action handler. There we have access to the `rootState` property that is exposed by the context received in the function. It is worthy of note that rootState is only available in modules option.

Assuming you want to access the state.users in users.js from admin.js

export const state = () => ({
    users: ''
})

export const mutations = {
    SET_USERS (state, users) {
        state.users = users
    }
}

export const actions = {
    setUsers ({ commit }, users) {
        commit('SET_USERS', users)
    },
}

export const getters = {
    users: state => state.users
}

Then in our admin.js module, we are going to have access to the state of the users by using rootState property available in the context received in the actions handler.

We will be using object destructuring introduced in ES6 to extract rootState.

export const state = () => ({
    //
})


export const mutations = {
	//
}

export const actions = {

    setUsers ({ rootState }) {

    	let users = rootState.users.users

        // Do whatever you like with users from users.js
    }
}

export const getters = {
	//
}

Conclusion

Context in the actions handler exposes rootState of our store to other modules.

Category
A Web Developer. Defender of WomenInTech. I love knowledge, I like learning, but knows next to nothing about Politics and Lies. Passionate about using technology to disrupt the way businesses are done.