Vuex源码解析(四) resetStoreVM

45 阅读1分钟

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())
  }
}