How to clear state in vuex store?

My condition in the vuex repository is huge.

Is there a way to reset all data in a state at a time, instead of manually setting everything to null?

+28
source share
10 answers

I just found a great solution that works for me.

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) { // Merge rather than replace so we don't lose observers // https://github.com/vuejs/vuex/issues/1118 Object.assign(state, getDefaultState()) } } export default { state, getters: {}, actions, mutations } 

Reset Vuex as a Professional

Thanks to Taha Shashtari for a great solution.

Michael,

+35
source

Update after using the solution below a little more

So it turns out that if you use replaceState with an empty object ( {} ), you end up blocking reactivity, as your states disappear. So basically you have to reset each property in state and then use store.replaceState(resetStateObject) . For a store without modules, you would do something like:

 let state = this.$store.state; let newState = {}; Object.keys(state).forEach(key => { newState[key] = null; // or = initialState[key] }); this.$store.replaceState(newState); 

Update (from comments). What if I need to reset / define only one module and leave the rest as is?

If you do not want to reset all your modules, you can simply reset the modules you need and leave the other reset in their current state.

For example, let's say you have several modules, and you only want to return module a to its initial state, using the method above ^, which we will call resetStateA . Then you should clone the initial state (which includes all the modules before reset).

 var currentState = deepClone(this.state) 

where deepClone is your deep clone method ( lodash has a good one ). This clone has the current state before reset. So let's rewrite this

 var newState = Object.assign(currentState, { a: resetStateA }); 

and use this new state with replaceState , which includes the current state of all your modules except module a with its initial state:

 this.$store.replaceState(newState); 

Original solution

I found this convenient method in Vuex.store . You can quickly and painlessly clear all states with replaceState , for example:

 store.replaceState({}) 

It works with a single repository or with modules and maintains the reactivity of all the properties of your state. See the Vuex api doc page and find the page for replaceState .

For modules

If you replace the store with modules, you will need to include empty status objects for each module. So, for example, if you have modules a and b , you should do:

 store.replaceState({ a: {}, b: {} }) 
+9
source

You can declare the initial state and reset this property of this property by property. You cannot just do state = initialState or lose reactivity.

Here's how we do it in the application I'm working on:

 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]) } } } 
+6
source

If you execute state = {}, you will remove the reactivity of the properties, and your mutations with getters will stop working.

you may have a sub-property like:

 state: { subProperty: { a: '', lot: '', of: '', properties: '', . . . } } 

Running state.subProperty = {} should help without losing reactivity.

You should not have too much state, break them into different modules and import into vuex repository as follows:

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

now in your separate files:

 // 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 } 

If you need to clear the state, you can simply implement the mutation:

 state[NameSpace.AUTH_STATE] = { auth: {}, error: null } 
+4
source

I'm not sure what you are using, but I needed to do something similar. When the user logs out, I want to clear all the state of the application, so I just did window.reload . Maybe not quite what you asked for, but if you want to clean the store, maybe an alternative.

+2
source

Based on these 2 answers ( # 1 # 2 ), I made workable code.

My Vuex index.js structure:

 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 

Inside each module, we need to move all the states to a separate var initialState and in the mutation define the resetState function, like media.js below for 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] }) }, } } 

In the Vue component, we can use it like this:

 <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
source

Call router.go() or this.$router.go()

This will refresh the page, and your state will be reset to the state that was when the user first downloaded the application.

+1
source

If you want to reset all state, you can use the built-in replaceState method.

Given the state set in index.js:

  const state = { user: '', token: '', products: [] /* etc. */ } const initialStateCopy = JSON.parse(JSON.stringify(state)) export const store = new Vuex.Store({ state, /* getters, mutations, etc. */ }) export function resetState() { store.replaceState(initialStateCopy) } 

Then in your vue component (or somewhere) import resetState :

  import { resetState } from '@/store/index.js' // vue component usage, for example: logout { // ... data(), computed etc. omitted for brevity methods: { logout() { resetState() } } } 
+1
source

Here is a solution that works in my application. I created a file called defaultState.js.

 //defaultState.js //the return value is the same as that in the state const defaultState = () => { return { items: [], poles: {}, ... } } export default defaultState 

And then where you want to use it

 //anywhere you want to use it //for example in your mutations.js //when you've gotten your store object do import defaultState from '/path/to/defaultState.js' let mutations = { ..., clearStore(state){ Object.assign(state, defaultState()) }, } export default mutations 

Then in your store.js

 import Vue from 'vue'; import Vuex from 'vuex'; import actions from './actions'; import getters from './getters'; import mutations from './mutations'; //import mutations import state from './state'; Vue.use(Vuex); export default new Vuex.Store({ actions, mutations, state, getters, }); 

what is it

+1
source

I read above and implemented the solution. can help you too !!

All objects stored in Vue act as observables . Thus, if the value reference is changed / changed , this will lead to a change in the actual value .

So, to reset the state, the original storage modules must be copied as a value .

When a user logs off, the same value must be assigned to each module as a copy.

This can be achieved as follows:

Step 1. Create a copy of the source module.

 // store.ts // Initial store with modules as an object export const initialStoreModules = { user, recruitment, }; export default new Vuex.Store({ /** * Assign the modules to the store * using lodash deepClone to avoid changing the initial store module values */ modules: _.cloneDeep(initialStoreModules), mutations: { // reset default state modules by looping around the initialStoreModules [types.RESET_STATE](state: any) { _.forOwn(initialStoreModules, (value: IModule, key: string) => { state[key] = _.cloneDeep(value.state); }); }, } }); 

Step 2: Call the action to convert the state to its original state.

 // user_action.ts const logout = ({ commit }: any) => { commit(types.LOGOUT_INIT); new UserProxy().logout().then((response: any) => { router.push({ name: 'login', }); // reset the state commit(types.RESET_STATE); }).catch((err: any) => { commit(types.LOGOUT_FAIL, err); }); }; 
0
source

Source: https://habr.com/ru/post/1015059/


All Articles