1- import { reactive , watch } from 'vue'
1+ import { reactive , computed , watch , effectScope } from 'vue'
22import { forEachValue , isObject , isPromise , assert , partial } from './util'
33
44export function genericSubscribe ( fn , subs , options ) {
@@ -29,30 +29,42 @@ export function resetStore (store, hot) {
2929
3030export function resetStoreState ( store , state , hot ) {
3131 const oldState = store . _state
32+ const oldScope = store . _scope
3233
3334 // bind store public getters
3435 store . getters = { }
3536 // reset local getters cache
3637 store . _makeLocalGettersCache = Object . create ( null )
3738 const wrappedGetters = store . _wrappedGetters
3839 const computedObj = { }
39- forEachValue ( wrappedGetters , ( fn , key ) => {
40- // use computed to leverage its lazy-caching mechanism
41- // direct inline function use will lead to closure preserving oldState.
42- // using partial to return function with only arguments preserved in closure environment.
43- computedObj [ key ] = partial ( fn , store )
44- Object . defineProperty ( store . getters , key , {
45- // TODO: use `computed` when it's possible. at the moment we can't due to
46- // https://github.com/vuejs/vuex/pull/1883
47- get : ( ) => computedObj [ key ] ( ) ,
48- enumerable : true // for local getters
40+ const computedCache = { }
41+
42+ // create a new effect scope and create computed object inside it to avoid
43+ // getters (computed) getting destroyed on component unmount.
44+ const scope = effectScope ( true )
45+
46+ scope . run ( ( ) => {
47+ forEachValue ( wrappedGetters , ( fn , key ) => {
48+ // use computed to leverage its lazy-caching mechanism
49+ // direct inline function use will lead to closure preserving oldState.
50+ // using partial to return function with only arguments preserved in closure environment.
51+ computedObj [ key ] = partial ( fn , store )
52+ computedCache [ key ] = computed ( ( ) => computedObj [ key ] ( ) )
53+ Object . defineProperty ( store . getters , key , {
54+ get : ( ) => computedCache [ key ] . value ,
55+ enumerable : true // for local getters
56+ } )
4957 } )
5058 } )
5159
5260 store . _state = reactive ( {
5361 data : state
5462 } )
5563
64+ // register the newly created effect scope to the store so that we can
65+ // dispose the effects when this method runs again in the future.
66+ store . _scope = scope
67+
5668 // enable strict mode for new state
5769 if ( store . strict ) {
5870 enableStrictMode ( store )
@@ -67,6 +79,11 @@ export function resetStoreState (store, state, hot) {
6779 } )
6880 }
6981 }
82+
83+ // dispose previously registered effect scope if there is one.
84+ if ( oldScope ) {
85+ oldScope . stop ( )
86+ }
7087}
7188
7289export function installModule ( store , rootState , path , module , hot ) {
0 commit comments