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。