Vuex Store
Watch a free lesson about Nuxt.js and Vuex on Vue School
Nuxt.js will look for the directory, if it exists, it will:
- Import Vuex,
- Add the
store
option to the root Vue instance. Nuxt.js lets you decide between 2 store modes. You can choose the one you prefer:
- Modules: every
.js
file inside thestore
directory is transformed as a (index
being the root module). - Classic (deprecated):
store/index.js
returns a method to create a store instance.
Regardless of the mode, your state
value should always be a function
to avoid unwanted shared state on the server side.
Modules mode
Nuxt.js lets you have a
store
directory with every file corresponding to a module.
To get started, export the state as a function, and the mutations and actions as objects in store/index.js
:
Then, you can have a store/todos.js
file:
export const state = () => ({
list: []
})
export const mutations = {
add (state, text) {
state.list.push({
text,
done: false
})
},
remove (state, { todo }) {
state.list.splice(state.list.indexOf(todo), 1)
},
toggle (state, todo) {
}
}
The store will be created as such:
new Vuex.Store({
state: () => ({
counter: 0
}),
mutations: {
increment (state) {
state.counter++
}
},
modules: {
namespaced: true,
state: () => ({
list: []
}),
mutations: {
add (state, { text }) {
state.list.push({
text,
done: false
})
},
remove (state, { todo }) {
state.list.splice(state.list.indexOf(todo), 1)
},
todo.done = !todo.done
}
}
}
}
})
And in your pages/todos.vue
, using the todos
module:
The module method also works for top-level definitions without implementing a sub-directory in the
store
directory
export default () => ({
counter: 0
})
And the corresponding mutations can be in the file store/mutations.js
export default {
increment (state) {
state.counter++
}
}
You can optionally break down a module file into separate files: state.js
, actions.js
, mutations.js
and getters.js
. If you maintain an file with state, getters and mutations while having a single separate file for actions, that will also still be properly recognized.
Plugins
You can add additional plugins to the store (in the modules mode) by putting them into the store/index.js
file:
More information about the plugins: Vuex documentation.
The
fetch
method is used to fill the store before rendering the page, it's like theasyncData
method except it doesn't set the component data.
More information about the fetch method: .
The nuxtServerInit Action
If the action nuxtServerInit
is defined in the store and the mode is universal
, Nuxt.js will call it with the context (only from the server-side). It's useful when we have some data on the server we want to give directly to the client-side.
For example, let's say we have sessions on the server-side and we can access the connected user through req.session.user
. To give the authenticated user to our store, we update our store/index.js
to the following:
actions: {
nuxtServerInit ({ commit }, { req }) {
if (req.session.user) {
commit('user', req.session.user)
}
}
}
The is given to nuxtServerInit
as the 2nd argument, it is the same as asyncData
or fetch
method.
If nuxt generate
is ran, nuxtServerInit
will be executed for every dynamic route generated.
actions: {
async nuxtServerInit({ dispatch }) {
await dispatch('core/load')
}
}
Strict mode is enabled by default on dev mode and turned off in production mode. To disable strict mode in dev, follow the below example in store/index.js
:
export const strict = false
Classic mode
This feature is deprecated and will be removed in Nuxt 3.
To activate the store with the classic mode, we create the store/index.js
file which should export a method that returns a Vuex instance:
We don't need to install
vuex
since it's shipped with Nuxt.js.
We can now use this.$store
inside our components:
<template>