How to clear state in vuex store?

后端 未结 12 1265
既然无缘
既然无缘 2020-12-23 12:21

My state in vuex store is huge.

Is there a way to reset all the data in state in one go, instead of manually setting everything to null?

相关标签:
12条回答
  • 2020-12-23 12:53

    Here's a solution that works in my app. I created a file named 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,
    });
    
    

    and That's it

    0 讨论(0)
  • 2020-12-23 12:56

    If it's the case such as logging out, you can just reload the page to set the store back to the base state.

    location.reload()
    
    0 讨论(0)
  • 2020-12-23 12:58

    Myself has read above and implemented a solution. could help you as well!!

    All objects stored in Vue act as an observable. So if reference of a value is changed/mutated it triggers the actual value to be changed too.

    So, Inorder to reset the state the initial store modules has to be copied as a value.

    On logging out of an user, the same value has to be assigned for each modules as a copy.

    This can be achieved as following:

    Step 1: Create a copy of your initial 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 mutate the state to initial 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 讨论(0)
  • 2020-12-23 13:04

    I am not sure what you use case is, but I had to do something similar. When a user logs out, I want to clear the entire state of the app - so I just did window.reload. Maybe not exactly what you asked for, but if this is why you want to clear the store, maybe an alternative.

    0 讨论(0)
  • 2020-12-23 13:11

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

    you can have a sub-property like:

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

    Doing a state.subProperty = {} should help, without losing the reactivity.

    You should not have a state too big, break them down to different modules and import to your vuex store like so:

    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 individual 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 should want to clear the state you can just have a mutation implement:

    state[NameSpace.AUTH_STATE] = {
      auth: {},
      error: null
    }
    
    0 讨论(0)
  • 2020-12-23 13:13

    I have just found the 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
    }
    

    Thanks to Taha Shashtari for the great solution.

    Michael,

    0 讨论(0)
提交回复
热议问题