How to clear state in vuex store?

后端 未结 12 1266
既然无缘
既然无缘 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 13:13

    You can declare an initial state and reset it to that state property by property. You can't just do state = initialState or you 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])
           }
        }
    }
    
    0 讨论(0)
  • 2020-12-23 13:13

    You could take it easy by tiny package: vuex-extensions

    Check out the example on CodeSandbox.

    Creating Vuex.Store

    import Vuex from 'vuex'
    import { createStore } from 'vuex-extensions'
    
    export default createStore(Vuex.Store, {
      plugins: []
      modules: {}
    })
    
    Store resets to initial State
    // Vue Component
    this.$store.reset()
    
    // Vuex action
    modules: {
      sub: {
        actions: {
          logout() {
            this.reset()
          }
        }
      }
    }
    
    0 讨论(0)
  • 2020-12-23 13:14

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

    That will refresh the page and your state will be reset to how it was when the user first loaded the app.

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

    Update after using the below solution a bit more

    So it turns out that if you use replaceState with an empty object ({}) you end up bricking reactivity since your state props go away. So in essence you have to actually reset every property in state and then use store.replaceState(resetStateObject). For store without modules you'd essentially 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 one needs to only reset/define a single module and keep the rest as they were?

    If you don't want to reset all your modules, you can just reset the modules you need and leave the other reset in their current state.

    For example, say you have mutliple modules and you only want to reset module a to it's initial state, using the method above^, which we'll call resetStateA. Then you would clone the original state (that includes all the modules before resetting).

    var currentState = deepClone(this.state)
    

    where deepClone is your deep cloning method of choice (lodash has a good one). This clone has the current state of A before the reset. So let's overwrite that

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

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

    this.$store.replaceState(newState);
    

    Original solution

    I found this handy method in Vuex.store. You can clear all state quickly and painlessly by using replaceState, like this:

    store.replaceState({})
    

    It works with a single store or with modules, and it preserves the reactivity of all your state properties. See the Vuex api doc page, and find in page for replaceState.

    For Modules

    IF you're replacing a store with modules you'll have to include empty state objects for each module. So, for example, if you have modules a and b, you'd do:

    store.replaceState({
      a: {},
      b: {}
    })
    
    0 讨论(0)
  • 2020-12-23 13:16

    If you want to reset your entire state you can use the built in replaceState method.

    Given a 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 anywhere) import resetState:

        import { resetState } from '@/store/index.js'
    
        // vue component usage, for example: logout
        {
          // ... data(), computed etc. omitted for brevity
          methods: {
            logout() { resetState() }
          }
        }
    
    0 讨论(0)
  • 2020-12-23 13:18

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

    My structure of Vuex's index.js:

    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 states into separated var initialState and in mutation define a function resetState, like 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 Vue component we can use it like:

    <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>
    
    0 讨论(0)
提交回复
热议问题