vue 中 this.$store 为 undefined 的问题

vue 中 this.$store 为空的问题,有部分网友遇到过,然后也用文字记下了解决方案。我左看右看,就是没能看到合适的。

比如 vue 实例化的时候忘记引入 store 了……

再比如引入 store 实力的时候首字母大写,然后 new Vue({ Store }) 这样……

再比如 store 文件没有将 store 实例默认导出……

……

这些问题我统统没有。但我的 this.$store 就是 undefined。

百思不得其解之际,想到了版本问题。或许是版本不对。看了下 package.json,vuex 用的 4.1.0,但 vue 是 2.6……

问题解决了,应该用 vuex3.x。

分别看一下两个版本 vuex 的部分源码,找找原因。

vuex3.x:

export default {
  Store,
  install,
  version: '__VERSION__',
  mapState,
  mapMutations,
  mapGetters,
  mapActions,
  createNamespacedHelpers
}

这里的导出是有 install 方法的,vue.use(Vuex) 的时候会调用 install 方法。

// install
export function install (_Vue) {
  if (Vue && _Vue === Vue) {
    if (__DEV__) {
      console.error(
        '[vuex] already installed. Vue.use(Vuex) should be called only once.'
      )
    }
    return
  }
  Vue = _Vue
  applyMixin(Vue)
}

// applyMixin
export default function (Vue) {
  const version = Number(Vue.version.split('.')[0])

  if (version >= 2) {
    Vue.mixin({ beforeCreate: vuexInit })
  } else {
    // override init and inject vuex init procedure
    // for 1.x backwards compatibility.
    const _init = Vue.prototype._init
    Vue.prototype._init = function (options = {}) {
      options.init = options.init
        ? [vuexInit].concat(options.init)
        : vuexInit
      _init.call(this, options)
    }
  }

  /**
   * Vuex init hook, injected into each instances init hooks list.
   */

  function vuexInit () {
    const options = this.$options
    // store injection
    if (options.store) {
      this.$store = typeof options.store === 'function'
        ? options.store()
        : options.store
    } else if (options.parent && options.parent.$store) {
      this.$store = options.parent.$store
    }
  }
}

通过 applyMixin 可以看到,对于 2.x 的 vue,vuex 会通过 mixin 将自身加入到 beforeCreate 钩子里,而对于 vue1.x 则劫持了 _init 方法 挂载 store。

好了,再来看看 vuex4.x

export default {
  version: '__VERSION__',
  Store,
  storeKey,
  createStore,
  useStore,
  mapState,
  mapMutations,
  mapGetters,
  mapActions,
  createNamespacedHelpers,
  createLogger
}

没有 install。所以 this.$store 自然就是 undefined。