web-dev-qa-db-fra.com

Comment effacer l'état dans le magasin Vuex?

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?

14
KaliCharan

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,

9
Michael Horojanski

Mettre à jour après avoir utilisé un peu plus la solution ci-dessous

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);

Mise à jour (à partir de commentaires): Que faire si on a seulement besoin de réinitialiser/définir un seul module et de garder le reste tel quel?

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)

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);

Solution originale

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.

Pour les modules

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: {}
})
5
seebiscuit

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])
       }
    }
}
4
For the Name

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
}
3
Amresh Venugopal

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.

2
xenetics

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>
1
TitanFighter