如何在vuex商店中清除状态?

时间:2017-02-17 10:21:41

标签: vue.js vuejs2 vuex

我在vuex商店的状态很大。

有没有办法一次性重置状态中的所有数据,而不是手动将所有数据设置为空?

14 个答案:

答案 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

对于模块

如果您要使用模块替换商店,则必须为每个模块包含空状态对象。因此,例如,如果您有模块bstore.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)

根据这两个答案(#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>

答案 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