如何清除 vuex 商店中的状态?
Posted
技术标签:
【中文标题】如何清除 vuex 商店中的状态?【英文标题】:How to clear state in vuex store? 【发布时间】:2017-07-06 19:50:42 【问题描述】:我在 vuex 商店的状态是巨大的。
有没有办法一次性重置所有状态数据,而不是手动将所有内容设置为空?
【问题讨论】:
重置是指将其设置为初始状态? 在我的情况下,清除数据与重置相同,因为我的商店最初是空的。 只是我的 2 便士,但我实际上分解了状态并加载了我正在使用的任何“核心”组件特有的存储。您可以在运行时使用 webpack 的异步导入方法导入特定的商店,并将其分配给您的 Vue 实例。不需要本机“模块”的东西,而且对您的客户来说更苗条。 为什么不使用@ianwalter/vuex-reset
?
【参考方案1】:
如果您清除了完整的 vuex 商店使用:
sessionStorage.clear();
【讨论】:
【参考方案2】: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
【讨论】:
【参考方案3】:你可以这样做
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()
【讨论】:
【参考方案4】:我刚刚找到了适合我的绝佳解决方案。
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
感谢 Taha Shashtari 的出色解决方案。
迈克尔,
【讨论】:
这是最好的解决方案 优秀的方法。为什么需要使用Object.assign(state, getDefaultState())
而不是state = getDefaultState()
?另外,为什么要有一个函数getDefaultState
而不仅仅是一个变量defaultState
?
@hitautodestruct,有一个问题解释了为什么需要通过以下方式重置状态github.com/vuejs/vuex/issues/1118。
@MichaelHorojanski 谢谢,我更新了您的答案,并附上了解释决定的小评论
请注意state
可以是一个函数,所以只需在导出中使用state: getDefaultState
而不是调用getDefaultState()
。【参考方案5】:
您可以通过小包装轻松解决问题: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()
【讨论】:
【参考方案6】:这是适用于我的应用的解决方案。我创建了一个名为 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,
);
就是这样
【讨论】:
状态不能直接改变,但是像这样的解决方案可以放在一个突变中 是的。我在突变中使用了我的 好的,如果代码在突变中,我会支持你的解决方案:) 更新@FrancescoVenturini【参考方案7】:我自己已阅读上述内容并实施了解决方案。也可以帮到你!!
存储在 Vue 中的所有对象都充当可观察对象。因此,如果一个值的reference被更改/变异,它会触发实际值也被更改。
因此,为了重置状态,必须将初始存储模块复制为值。
在用户注销时,必须为每个模块分配相同的值作为副本。
这可以通过以下方式实现:
第 1 步:创建初始模块的副本。
// 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);
);
,
);
第 2 步:调用操作以将状态改变为初始状态。
// 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);
);
;
【讨论】:
【参考方案8】:如果你想重置你的整个状态,你可以使用内置的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()
【讨论】:
【参考方案9】:致电router.go()
或this.$router.go()
这将刷新页面,您的状态将重置为用户首次加载应用时的状态。
【讨论】:
localStorage.clear(); this.$router.go();
救了我!【参考方案10】:
在使用以下解决方案后更新
所以事实证明,如果你使用 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);
更新(来自 cmets):如果只需要重置/定义一个模块并保持其余模块不变怎么办?
如果您不想重置所有模块,您可以只重置您需要的模块,并将其他重置保留在当前状态。
例如,假设您有多个模块,并且您只想将模块a
重置为其初始状态,使用上面的方法^,我们将其称为resetStateA
。然后您将克隆原始状态(包括所有模块之前重置)。
var currentState = deepClone(this.state)
deepClone
是您选择的深度克隆方法 (lodash has a good one)。此克隆在重置之前具有 A 的当前状态。所以让我们覆盖它
var newState = Object.assign(currentState,
a: resetStateA
);
并将新状态与 replaceState
一起使用,其中包括所有模块的当前状态,但模块 a
及其初始状态除外:
this.$store.replaceState(newState);
原解决方案
我在Vuex.store
中找到了这个方便的方法。您可以使用replaceState
快速轻松地清除所有状态,如下所示:
store.replaceState()
它适用于单个存储或模块,并且它保留了所有状态属性的反应性。查看Vuex api doc page,并在页面中找到replaceState
。
对于模块
如果您要用模块替换商店,则必须为每个模块包含空状态对象。因此,例如,如果你有模块 a
和 b
,你会这样做:
store.replaceState(
a: ,
b:
)
【讨论】:
出于某种原因,在我的情况下,For Modules
部分的代码需要重新加载页面才能重置所有内容。
Vue 建议仅将replaceState
用于时间旅行。如果只需要重置/定义一个模块并保持其余部分不变怎么办。怎么做呢?我尝试使用mutations
,但如果没有被盯着看,就会抛出undefined
。
@KasparTr 我更新了答案以处理您的问题。希望对您有所帮助!
@seebiscuit 感谢您的更新。在这种情况下,是的,您正在用它的所有模块替换整个状态。我想我的问题是你如何优雅地只替换一个模块而保留其他模块。现在我通过突变来做到这一点。
是的,@KasparTr,replaceState
的缺点是它需要所有模块状态。但是,如果您不希望每秒重复此操作多次,或者您的状态不是几兆字节大,那么您可以争辩说性能损失值得过程的可读性和大小。【参考方案11】:
基于这 2 个答案 (#1#2) 我编写了一个可行的代码。
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>
【讨论】:
【参考方案12】:我不确定您的用例是什么,但我必须做类似的事情。当用户注销时,我想清除应用程序的整个状态 - 所以我只是做了window.reload
。也许不完全符合您的要求,但如果这就是您想要清空商店的原因,也许是另一种选择。
【讨论】:
这似乎是最简单的解决方案,因为我正在注销,所以在我看来,重新加载窗口以清除商店并路由到登录页面并没有什么害处。除非 vue 可以更简单地自动设置初始状态(在我的情况下为空 '' ),否则应该有类似这样的东西。$store.clear(); 取决于用例。这只会把一切都搞砸,如果我们正在执行“完全重置”(例如用户注销),我们并不真正关心保持反应性或状态(实际上,我们想摆脱一切)。 我想你现在更愿意window.location.reload
如果你使用 vuex-persistedstate 这将不起作用【参考方案13】:
您可以声明一个初始状态并将其按属性重置为该状态属性。你不能只做 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])
【讨论】:
【参考方案14】:如果您执行 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
【讨论】:
以上是关于如何清除 vuex 商店中的状态?的主要内容,如果未能解决你的问题,请参考以下文章