Nuxt.js — Vuex

John Au-Yeung - Jan 26 '21 - - Dev Community

Check out my books on Amazon at https://www.amazon.com/John-Au-Yeung/e/B08FT5NT62

Subscribe to my email list now at http://jauyeung.net/subscribe/

Nuxt.js is an app framework that’s based on Vue.js.

We can use it to create server-side rendered apps and static sites.

In this article, we’ll look at how to use Vuex with Nuxt.

Activate the Store

Vuex is built into Nuxt.

We can just import it and add the store option to the root Vue instance.

To add the store, we can write:

store/index.js

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

export const mutations = {
  increment(state) {
    state.counter++
  }
}
Enter fullscreen mode Exit fullscreen mode

We created a root module for our Vuex store since the code is in the index.js file.

Then we can use it by writing:

page/counter.vue

<template>
  <div class="container">
    <button @click="increment">increment</button>
    <p>{{counter}}</p>
  </div>
</template>

<script>
export default {
  computed: {
    counter() {
      return this.$store.state.counter;
    },
  },
  methods: {
    increment() {
      this.$store.commit('increment');
    },
  },
};
</script>
Enter fullscreen mode Exit fullscreen mode

We have access to the this.$store object.

The state property has the state.

And the commit method lets us run a mutation.

To create a namespaced module, we can change the name of the store file.

For example, we can create a store/counter.js file and write:

export const state = () => ({
  count: 0
})

export const mutations = {
  increment(state) {
    state.count++
  }
}
Enter fullscreen mode Exit fullscreen mode

Then we can access the counter module by writing:

<template>
  <div class="container">
    <button @click="increment">increment</button>
    <p>{{count}}</p>
  </div>
</template>

<script>
import { mapMutations } from "vuex";

export default {
  computed: {
    count() {
      return this.$store.state.counter.count;
    },
  },
  methods: {
    increment() {
      this.$store.commit('counter/increment');
    },
  },
};
</script>
Enter fullscreen mode Exit fullscreen mode

We add the namespace to access the state and commit our actions.

Also, we can use the map methods from Vuex to map the getters, mutations, and actions to properties in our component.

For example, we can write:

<template>
  <div class="container">
    <button @click="increment">increment</button>
    <p>{{count}}</p>
  </div>
</template>

<script>
import { mapMutations } from "vuex";

export default {
  computed: {
    count() {
      return this.$store.state.counter.count;
    },
  },
  methods: {
    ...mapMutations({
      increment: "counter/increment",
    }),
  },
};
</script>
Enter fullscreen mode Exit fullscreen mode

to map our counter/increment mutation to the increment method with the mapMutations method.

Plugins

We can add Vuex plugins to our Vuex store.

For example, we can add the Vuex logger to our app by writing:

store/index.js

import createLogger from 'vuex/dist/logger'

export const plugins = [createLogger()]

export const state = () => ({
  count: 0
})

export const mutations = {
  increment(state) {
    state.count++
  }
}
Enter fullscreen mode Exit fullscreen mode

We just export the plugins array to add our plugins.

The nuxtServerInit Action

The nuxtServerInit action is defined in the store.

This runs in any environment.

To use it, we can add it to our store by writing:

store/index.js

export const actions = {
  nuxtServerInit({ commit }, { req }) {
    commit('core/load', { foo: 'bar' })
  }
}
Enter fullscreen mode Exit fullscreen mode

store/core.js

export const state = () => ({
  obj: {}
})

export const mutations = {
  load(state, payload) {
    state.obj = payload;
  }
}
Enter fullscreen mode Exit fullscreen mode

foo.vue

<template>
  <div class="container">{{obj}}</div>
</template>

<script>
export default {
  computed: {
    obj() {
      return this.$store.state.core.obj;
    },
  },
};
</script>
Enter fullscreen mode Exit fullscreen mode

We have the nuxtServerInit action in the root module.

It has the commit function to let us commit mutations.

req is the request object.

Conclusion

We can add a Vuex store to an Nuxt app with a few changes.

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .