我在vuex商店的状态很大。
有没有办法一次性重置状态中的所有数据,而不是手动将所有数据设置为空?
答案 0 :(得分:18)
我刚刚找到了适合我的出色解决方案。
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 Module State Like a Pro
感谢Taha Shashtari的出色解决方案。
迈克尔
答案 1 :(得分:5)
您可以声明初始状态并按属性将其重置为该状态属性。你不能只做state = initialState或者你失去反应。
以下是我们如何在我正在处理的应用程序中执行此操作:
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])
}
}
}
答案 2 :(得分:5)
事实证明,如果你将replaceState
与一个空对象({}
)一起使用,那么你的状态道具就会消失,最终会阻止反应。所以实质上你必须实际重置状态中的每个属性,然后使用store.replaceState(resetStateObject)
。对于没有模块的商店,您基本上可以执行以下操作:
let state = this.$store.state;
let newState = {};
Object.keys(state).forEach(key => {
newState[key] = null; // or = initialState[key]
});
this.$store.replaceState(newState);
如果您不想重置所有模块,只需重置所需的模块,并将其他模块保持当前状态即可。
例如,假设您有多个模块,并且您只想使用上面的方法^ a
重置模块resetStateA
到它的初始状态,我们将调用var currentState = deepClone(this.state)
。然后,您将克隆原始状态(包括重置之前的所有模块)。
deepClone
其中var newState = Object.assign(currentState, {
a: resetStateA
});
是您选择的深度克隆方法(lodash has a good one)。 重置之前,此克隆具有A 的当前状态。所以,让我们覆盖
replaceState
并使用a
的新状态,其中包括所有模块的当前状态,但模块this.$store.replaceState(newState);
的初始状态除外:
Vuex.store
我在replaceState
找到了这个方便的方法。您可以使用store.replaceState({})
快速轻松地清除所有状态,如下所示:
replaceState
它适用于单个商店或模块,它保留了所有州属性的反应性。请参阅Vuex api doc page,然后在页面中查找a
。
如果您要使用模块替换商店,则必须为每个模块包含空状态对象。因此,例如,如果您有模块b
和store.replaceState({
a: {},
b: {}
})
,那么您可以:
this
答案 3 :(得分:3)
如果你执行state = {},你将删除属性的反应性,你的getter突变将突然停止工作。
你可以有一个子属性,如:
state: {
subProperty: {
a: '',
lot: '',
of: '',
properties: '',
.
.
.
}
}
执行state.subProperty = {}应该有所帮助,而不会失去反应性。
你不应该有一个太大的状态,将它们分解为不同的模块并导入你的vuex商店,如下所示:
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
}
})
现在在您的个人档案中:
// 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
}
如果您想要清除状态,您可以使用变异工具:
state[NameSpace.AUTH_STATE] = {
auth: {},
error: null
}
答案 4 :(得分:2)
我不确定你使用的是什么案例,但我必须做类似的事情。当用户注销时,我想清除应用程序的整个状态 - 所以我只是window.reload
。也许不完全是你要求的,但如果这就是为什么你要清理商店,也许是另一种选择。
答案 5 :(得分:1)
我的Vuex 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
在每个模块中,我们需要将所有状态移动到分离的var initialState
中,并在变异中定义函数resetState
,如下面的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] })
},
}
}
在Vue组件中,我们可以使用它:
<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>
答案 6 :(得分:1)
这是在我的应用中有效的解决方案。我创建了一个名为defaultState.js的文件。
//defaultState.js
//the return value is the same as that in the state
const defaultState = () => {
return {
items: [],
poles: {},
...
}
}
export default defaultState
然后在您想使用的地方
//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
然后在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,
});
就这样
答案 7 :(得分:1)
您可以通过小型包装轻松实现:vuex-extensions
在CodeSandbox上查看示例。
创建Vuex.Store
import Vuex from 'vuex'
import { createStore } from 'vuex-extensions'
export default createStore(Vuex.Store, {
plugins: []
modules: {}
})
将重置存储到初始状态
// Vue Component
this.$store.reset()
// Vuex action
modules: {
sub: {
actions: {
logout() {
this.reset()
}
}
}
}
答案 8 :(得分:1)
在这种情况下(例如注销),您只需重新加载页面即可将商店设置回基本状态。
location.reload()
答案 9 :(得分:0)
致电router.go()
或this.$router.go()
这将刷新页面,并且您的状态将重置为用户首次加载应用程序时的状态。
答案 10 :(得分:0)
如果您想重置整个状态,则可以使用内置的replaceState
方法。
给出在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)
}
然后在vue组件(或任何位置)中导入resetState
:
import { resetState } from '@/store/index.js'
// vue component usage, for example: logout
{
// ... data(), computed etc. omitted for brevity
methods: {
logout() { resetState() }
}
}
答案 11 :(得分:0)
我自己已阅读以上内容并实施了解决方案。也可以帮助您!
存储在Vue中的所有对象都是可观察的。因此,如果引用值被更改/突变,则会触发实际值也被更改。
因此,为了重置,必须将初始存储模块的状态复制为值。
注销用户时,必须为每个模块分配相同的值作为副本。
这可以通过以下方式实现:
步骤1: 。创建初始模块的副本。
var firebaseApp = firebase.initializeApp(config);
var database = firebase.firestore();
database.collection('activities')
.get()
.then(qs => qs.docs.forEach(doc => console.log(doc.data())))
.then(() => {
console.log('done.');
firebaseApp.delete();
// database.disableNetwork(); // Another way to do this, though not as clean
});
第2步: 调用将状态更改为初始状态的操作。
// 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);
});
},
}
});
答案 12 :(得分:0)
你可以这样做
index.js
...
const store = new Vuex.Store({
modules: {
...
}
})
store.initialState = clone(store.state)
store.resetState = () => {
store.replaceState(store.initialState)
}
export default store
其他地方
this.$store.resetState()
答案 13 :(得分:0)
function initialState () {
return { /* .. initial state ... */ }
}
export default {
state: initialState,
mutations: {
reset (state) {
// acquire initial state
const s = initialState()
Object.keys(s).forEach(key => {
state[key] = s[key]
})
}
}
}
这是官方推荐 issue