Mon état dans le magasin de vuex est énorme.
Existe-t-il un moyen de réinitialiser toutes les données dans l'état en une fois, au lieu de tout définir manuellement sur null?
Je viens de trouver la grande solution qui fonctionne pour moi.
const getDefaultState = () => {
return {
items: [],
status: 'empty'
}
}
// initial state
const state = getDefaultState()
const actions = {
resetCartState ({ commit }) {
commit('resetState')
},
addItem ({ state, commit }, item) { /* ... */ }
}
const mutations = {
resetState (state) {
Object.assign(state, getDefaultState())
}
}
export default {
state,
getters: {},
actions,
mutations
}
Réinitialiser l’état du module Vuex comme un pro
Merci à Taha Shashtari pour cette excellente solution.
Michael,
Il s'avère donc que si vous utilisez replaceState
avec un objet vide ({}
), vous finissez par créer une réactivité inquiétante puisque vos accessoires d'état disparaissent. Vous devez donc essentiellement réinitialiser chaque propriété dans l'état, puis utiliser store.replaceState(resetStateObject)
. Pour magasin sans modules, vous feriez essentiellement quelque chose comme:
let state = this.$store.state;
let newState = {};
Object.keys(state).forEach(key => {
newState[key] = null; // or = initialState[key]
});
this.$store.replaceState(newState);
Si vous ne souhaitez pas réinitialiser tous vos modules, vous pouvez simplement réinitialiser les modules dont vous avez besoin et laisser l'autre réinitialisation dans son état actuel.
Par exemple, supposons que vous ayez plusieurs modules et que vous souhaitiez uniquement réinitialiser le module a
à son état initial, à l'aide de la méthode ci-dessus ^, que nous appellerons resetStateA
. Ensuite, vous cloneriez l’état initial (qui comprend tous les modules avant réinitialisation).
var currentState = deepClone(this.state)
où deepClone
est votre méthode de clonage en profondeur de choix ( lodash en a une bonne ). Ce clone a l'état actuel de A avant la réinitialisation. Alors écrasons cela
var newState = Object.assign(currentState, {
a: resetStateA
});
et utilisez ce nouvel état avec replaceState
, qui comprend l'état actuel de tous vos modules, à l'exception du module a
avec son état initial:
this.$store.replaceState(newState);
J'ai trouvé cette méthode pratique dans Vuex.store
. Vous pouvez effacer tous les états rapidement et sans douleur en utilisant replaceState
, comme ceci:
store.replaceState({})
Cela fonctionne avec un seul magasin ou avec des modules, et préserve la réactivité de toutes vos propriétés d'état. Voir la page Vuex api doc , et trouver dans la page pour replaceState
.
SI vous remplacez un magasin par des modules, vous devrez inclure des objets d'état vides pour chaque module. Ainsi, par exemple, si vous avez les modules a
et b
, vous feriez:
store.replaceState({
a: {},
b: {}
})
Vous pouvez déclarer un état initial et le réinitialiser sur cette propriété d'état, propriété par propriété. Vous ne pouvez pas simplement faire état = initialState ou vous perdez en réactivité.
Voici comment nous procédons dans l'application sur laquelle je travaille:
let initialState = {
"token": null,
"user": {}
}
const state = Vue.util.extend({}, initialState)
const mutations = {
RESET_STATE(state, payload) {
for (let f in state) {
Vue.set(state, f, initialState[f])
}
}
}
Si vous faites un état = {}, vous supprimerez la réactivité des propriétés et les mutations de vos accesseurs cesseront soudainement de fonctionner.
vous pouvez avoir une sous-propriété comme:
state: {
subProperty: {
a: '',
lot: '',
of: '',
properties: '',
.
.
.
}
}
Faire un état.subProperty = {} devrait aider, sans perdre la réactivité.
Vous ne devriez pas avoir un état trop grand, décomposez-les en différents modules et importez-les dans votre magasin Vuex comme suit:
import Vue from 'vue'
import Vuex from 'vuex'
import authorization from './modules/authorization'
import profile from './modules/profile'
Vue.use(Vuex)
export const store = new Vuex.Store({
modules: {
authorization,
profile
}
})
maintenant dans vos dossiers individuels:
// modules/authorization.js
import * as NameSpace from '../NameSpace'
import { someService } from '../../Services/something'
const state = {
[NameSpace.AUTH_STATE]: {
auth: {},
error: null
}
}
const getters = {
[NameSpace.AUTH_GETTER]: state => {
return state[NameSpace.AUTH_STATE]
}
}
const mutations = {
[NameSpace.AUTH_MUTATION]: (state, payload) => {
state[NameSpace.AUTH_STATE] = payload
},
}
const actions = {
[NameSpace.ASYNC_AUTH_ACTION]: ({ commit }, payload) => {
someService.login(payload.username, payload.password)
.then((user) => {
commit(NameSpace.AUTH_MUTATION, {auth: user, error: null})
})
.catch((error) => {
commit(NameSpace.AUTH_MUTATION, {auth: [], error: error})
})
}
}
export default {
state,
getters,
mutations,
actions
}
Si vous voulez effacer cet état, vous pouvez simplement implémenter une mutation:
state[NameSpace.AUTH_STATE] = {
auth: {},
error: null
}
Je ne sais pas ce que vous utilisez comme cas, mais je devais faire quelque chose de similaire. Lorsqu'un utilisateur se déconnecte, je souhaite effacer l'état complet de l'application. Je viens donc de faire window.reload
. Peut-être pas exactement ce que vous avez demandé, mais si c'est la raison pour laquelle vous souhaitez vider le magasin, peut-être une alternative.
Sur la base de ces 2 réponses ( # 1# 2 ), j'ai créé un code exploitable.
Ma structure du index.js
de Vuex:
import Vue from 'vue'
import Vuex from 'vuex'
import createPersistedState from 'vuex-persistedstate'
import { header } from './header'
import { media } from './media'
Vue.use(Vuex)
const store = new Vuex.Store({
plugins: [createPersistedState()],
modules: {
header,
media
}
})
export default store
Dans chaque module, nous devons déplacer tous les états dans des variables séparées var initialState
et en mutation définir une fonction resetState
, comme ci-dessous pour media.js
:
const initialState = () => ({
stateOne: 0,
stateTwo: {
isImportedSelected: false,
isImportedIndeterminate: false,
isImportedMaximized: false,
isImportedSortedAsc: false,
items: [],
stateN: ...
}
})
export const media = {
namespaced: true,
state: initialState, // <<---- Our States
getters: {
},
actions: {
},
mutations: {
resetState (state) {
const initial = initialState()
Object.keys(initial).forEach(key => { state[key] = initial[key] })
},
}
}
Dans le composant Vue, nous pouvons l'utiliser comme:
<template>
</template>
<script>
import { mapMutations } from 'vuex'
export default {
name: 'SomeName',
data () {
return {
dataOne: '',
dataTwo: 2
}
},
computed: {
},
methods: {
...mapMutations('media', [ // <<---- define module
'resetState' // <<---- define mutation
]),
logout () {
this.resetState() // <<---- use mutation
// ... any code if you need to do something here
}
},
mounted () {
}
} // End of 'default'
</script>
<style>
</style>