重置 清除 vuex store

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

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
}
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>
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);
    });
};
shar
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() }
      }
    }
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值