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?
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
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()
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);
});
};
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.
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
}
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,