Vuexストアでの私の状態は巨大です。
すべてを手動でnullに設定する代わりに、状態のすべてのデータを一度にリセットする方法はありますか?
私はちょうど私のために働く素晴らしいソリューションを見つけました。
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に感謝します。
マイケル、
そのため、空のオブジェクト({}
)で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
を初期状態にのみリセットしたいとします。次に、元の状態(すべてのモジュールを含むbefore resetting)を複製します。
var currentState = deepClone(this.state)
ここで、deepClone
は、選択するディープクローン方法です( lodashには良い方法があります )。このクローンの現在の状態はA before resetです。それを上書きしましょう
var newState = Object.assign(currentState, {
a: resetStateA
});
その新しい状態をreplaceState
で使用します。これには、初期状態のa
モジュールを除く、すべてのモジュールの現在の状態が含まれます。
this.$store.replaceState(newState);
Vuex.store
でこの便利なメソッドを見つけました。次のようにreplaceState
を使用すると、すべての状態をすばやく簡単にクリアできます。
store.replaceState({})
単一のストアまたはモジュールで動作し、すべての状態プロパティの反応性を保持します。 Vuex APIドキュメントページ を参照し、replaceState
のページを見つけます。
ストアをモジュールに置き換える場合、各モジュールに空の状態オブジェクトを含める必要があります。したがって、たとえば、モジュールa
およびb
がある場合、次のようにします。
store.replaceState({
a: {},
b: {}
})
プロパティごとに初期状態を宣言し、その状態にリセットできます。 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])
}
}
}
State = {}を実行すると、プロパティの反応性が削除され、ゲッターの突然変異が突然機能しなくなります。
次のようなサブプロパティを持つことができます。
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
}
あなたがどのようなケースを使用しているかはわかりませんが、似たようなことをしなければなりません。ユーザーがログアウトしたら、アプリの状態全体を消去したいので、window.reload
を実行しました。たぶん正確にあなたが求めたものではないかもしれませんが、これがあなたが店をクリアしたい理由であるなら、多分代替案。
router.go()
またはthis.$router.go()
を呼び出します
ページが更新され、状態はユーザーが最初にアプリをロードしたときの状態にリセットされます。
これらの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>
状態全体をリセットする場合は、組み込みの 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() }
}
}
私自身は上記を読み、解決策を実装しました。あなたも助けることができます!!
すべてのオブジェクトはVueに格納され、observableとして機能します。したがって、値の参照が変更/変更の場合、変更される実際の値がトリガーされます。
そのため、resetの状態は初期ストアモジュールが値としてコピーである必要があります。
ユーザーからログアウトするとき、コピーとして同じ値を各モジュールに割り当てられるにする必要があります。
これは次のように実現できます。
ステップ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);
});
};
これが私のアプリで動作するソリューションです。 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,
});
以上です