title | description |
---|---|
Vuex Store |
L'utilisation d'un store pour gérer l'état est important pour toutes les applications de taille importante, c'est pourquoi Vuex est implémenté au cœur de Nuxt.js. |
L'utilisation d'un store pour gérer l'état est important pour toutes les applications de taille importante, c'est pourquoi Vuex est implémenté au cœur de Nuxt.js.
Nuxt.js recherchera le répertoire store
. S'il existe, il :
- importera Vuex,
- ajoutera le module
vuex
dans le paquetage vendors, - ajoutera l'option
store
à l'instance racine de Vue.
Nuxt.js vous laisse le choix entre 2 modes de store, choisissez celui qui vous convient le mieux :
- Classique :
store/index.js
retourne une instance. - Modules : chaque fichier
.js
dans le répertoirestore
est transformé en tant que module avec son propre espace de nom (index
étant le module racine)
Pour activer le store avec le mode classique, nous créons store/index.js
dans lequel nous exportons l'instance du store :
import Vuex from 'vuex'
const createStore = () => {
return new Vuex.Store({
state: {
counter: 0
},
mutations: {
increment (state) {
state.counter++
}
}
})
}
export default createStore
Pas besoin d'installer
vuex
, celui-ci étant livré avec Nuxt.js.
Nous pouvons alors utiliser this.$store
dans nos composants :
<template>
<button @click="$store.commit('increment')">{{ $store.state.counter }}</button>
</template>
Nuxt.js vous permet d'avoir un répertoire
store
dans lequel chaque fichier correspond à un module.
Si vous voulez cette option, exportez l'état, les mutations et les actions dans store/index.js
au lieu de l'instance store
:
export const state = () => ({
counter: 0
})
export const mutations = {
increment (state) {
state.counter++
}
}
Puis, vous pouvez avoir store/todos.js
:
export const state = () => ({
list: []
})
export const mutations = {
add (state, text) {
state.list.push({
text: text,
done: false
})
},
remove (state, { todo }) {
state.list.splice(state.list.indexOf(todo), 1)
},
toggle (state, todo) {
todo.done = !todo.done
}
}
Le store sera comme suit :
new Vuex.Store({
state: { counter: 0 },
mutations: {
increment (state) {
state.counter++
}
},
modules: {
todos: {
state: {
list: []
},
mutations: {
add (state, { text }) {
state.list.push({
text,
done: false
})
},
remove (state, { todo }) {
state.list.splice(state.list.indexOf(todo), 1)
},
toggle (state, { todo }) {
todo.done = !todo.done
}
}
}
}
})
Et dans votre pages/todos.vue
, utiliser le module todos
:
<template>
<ul>
<li v-for="todo in todos">
<input type="checkbox" :checked="todo.done" @change="toggle(todo)">
<span :class="{ done: todo.done }">{{ todo.text }}</span>
</li>
<li><input placeholder="Qu'est-ce qui doit être fait ?" @keyup.enter="addTodo"></li>
</ul>
</template>
<script>
import { mapMutations } from 'vuex'
export default {
computed: {
todos () { return this.$store.state.todos.list }
},
methods: {
addTodo (e) {
this.$store.commit('todos/add', e.target.value)
e.target.value = ''
},
...mapMutations({
toggle: 'todos/toggle'
})
}
}
</script>
<style>
.done {
text-decoration: line-through;
}
</style>
Vous pouvez ajouter des plugins additionnels au store (en mode modules) en les ajoutant dans le fichier store/index.js
:
import myPlugin from 'myPlugin'
export const plugins = [ myPlugin ]
export const state = () => ({
counter: 0
})
export const mutations = {
increment (state) {
state.counter++
}
}
Pour plus d'informations à propos des plugins, consultez la documentation Vuex.
La méthode
fetch
est utilisée pour remplir le store avant de faire le rendu de la page, c'est comme la méthodedata
sauf qu'elle ne définit pas les données du composant.
Plus d'informations à propos de la méthode fetch
dans la partie Pages de l'API pour fetch
.
Si l'action nuxtServerInit
est définie dans le store, Nuxt.js l'appellera avec le contexte (uniquement côté serveur). C'est utile lorsque nous disposons de données sur le serveur que nous voulons donner directement au client.
Par exemple, disons que nous avons des sessions côté serveur et nous pouvons accéder à l'utilisateur connecté grâce à req.session.user
. Pour fournir l'utilisateur authentifié à notre store, nous mettons à jour notre store/index.js
comme suit :
actions: {
nuxtServerInit ({ commit }, { req }) {
if (req.session.user) {
commit('user', req.session.user)
}
}
}
Si vous utilisez le mode Modules du store Vuex, seul le module principal (dans
store/index.js
) recevra cette action. Vous devrez chainer vos actions de module à partir de là.
Le contexte est fourni par nuxtServerInit
comme deuxième argument. C'est le même que pour les méthodes data
et fetch
excepté que context.redirect()
et context.error()
sont omis.
Note : Les actions
nuxtServerInit
asynchrones doivent retourner une promesse pour permettre au serveurnuxt
de les attendres.