Skip to content

Commit

Permalink
feat(store): don't use replaceState anymore
Browse files Browse the repository at this point in the history
replaceState API wouldn't trigger vue-devtool
  • Loading branch information
lbwa committed Mar 7, 2020
1 parent 933eb34 commit 2b5c7d4
Show file tree
Hide file tree
Showing 4 changed files with 42 additions and 19 deletions.
18 changes: 9 additions & 9 deletions src/plugins/store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@ import { Plugin } from 'vuex'
import { RootState } from '@/store/global'
import cloneDeep from 'lodash.clonedeep'

export const createResetPlugin: (
listenType: string
) => Plugin<RootState> = listenType => store => {
const stateClone = cloneDeep(store.state)

store.subscribeAction(action => {
if (action.type !== listenType) return
store.replaceState(stateClone)
})
/**
* For storing the whole initial `store.state` including all modules states
* @when This plugin will be called only once in the whole Store instance lifetime
* @see https://github.com/vuejs/vuex/blob/v3.1.2/src/store.js#L64-L65
*/
export const createResetPlugin: () => Plugin<RootState> = () => store => {
const clone = cloneDeep(store.state)
delete clone.DO_NOT_MUTATE
store.commit('setSnapshot', clone)
}
39 changes: 31 additions & 8 deletions src/store/global.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,40 @@
export type RootState = {}
import { GetterTree, MutationTree, ActionTree } from 'vuex'
import cloneDeep from 'lodash.clonedeep'

const globalNamespace = {
state: {} as RootState,
export type RootState = {
DO_NOT_MUTATE: RootState
}

interface GlobalNamespaces {
state: RootState
getters: GetterTree<RootState, RootState>
mutations: MutationTree<RootState>
actions: ActionTree<RootState, RootState>
}

const globalNamespace: GlobalNamespaces = {
state: {
// DO NOT mutate this snapshot property for the entire store.state
// This is should be use to reset state
DO_NOT_MUTATE: {} as RootState
},

getters: {},

mutations: {},
mutations: {
// should always pass a store.state deep clone, instead of reference
setSnapshot(state, snapshot) {
state.DO_NOT_MUTATE = snapshot
},
resetState(state, replacement: RootState) {
// should always use a deep clone from snapshot to avoid unexpected snapshot mutation
Object.assign(state, cloneDeep(replacement))
}
},

actions: {
resetStore() {
/**
* This action will trigger store reset plugin in src/plugins/store.ts
*/
resetState({ commit, rootState }) {
commit('resetState', rootState.DO_NOT_MUTATE)
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/store/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { createResetPlugin } from '../plugins/store'
Vue.use(Vuex)

const plugins = (() => {
const plugins = [createResetPlugin('resetStore')]
const plugins = [createResetPlugin()]
if (__DEV__) {
plugins.push(createLogger())
}
Expand Down
2 changes: 1 addition & 1 deletion src/store/modules/user.ts
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ const user: Module<UserState, RootState> = {
},
async logout({ dispatch }, router: VueRouter) {
reset(router)
await dispatch('resetStore', null, { root: true })
await dispatch('resetState', null, { root: true })
router.push({
name: 'Login'
})
Expand Down

0 comments on commit 2b5c7d4

Please sign in to comment.