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。