resetStoreVM
做的事情:
- 重置 store
- 遍历 _wrappedGetters 的属性,代理对 store.getters 的访问
- 将 state 放到 Vue 实例的 $$state 上【 $ 开头的属性无法直接通过 this.xx 访问】
- 将 getters 的懒执行 也是依赖 computed
- 判读是不是严格模式,若是则只能在 mutation 方法更改 state
- 判断 是否存在 vue 实例如果有在 nextTicker 中销毁旧实例
/**
* @param {Store} store store
* @param {Store.state} state state
* @param {Boolean} hot
*/
function resetStoreVM (store, state, hot) {
// 保存旧的 实例
const oldVm = store._vm
// 每次都要清空 getters
store.getters = {}
// 纯空对象, 用来 做 getters 缓存
store._makeLocalGettersCache = Object.create(null)
// 收集 getters 方法, 并且保存 wrappedGetters
const wrappedGetters = store._wrappedGetters
// 用来做 getters 缓存
const computed = {}
// forEachValue 方法就是把对象的key value 都遍历出来
// 给每个属性做代理 对于 wrappedGetters
forEachValue(wrappedGetters, (fn, key) => {
computed[key] = partial(fn, store)
Object.defineProperty(store.getters, key, {
get: () => store._vm[key],
enumerable: true
})
})
const silent = Vue.config.silent
Vue.config.silent = true
// 将 state 和 getters 挂载到 Vue 实例上
// $$state 代理上
store._vm = new Vue({
data: {
$$state: state
},
computed
})
Vue.config.silent = silent
// 是否为严格模式 如果是则 state 只能通过 mutation 更改 通过其他
if (store.strict) {
enableStrictMode(store)
}
if (oldVm) {
if (hot) {
store._withCommit(() => {
oldVm._data.$$state = null
})
}
Vue.nextTick(() => oldVm.$destroy())
}
}