通过 vue.use(Vuex) 开始执行 Vuex.install(_vue) 方法
Vuex.install 不是来自于 Store 类对象,而是一个在 Store.js 文件中单独写的一个函数。
# /src/store.js 文件
import applyMixin from './mixin'
/**
Vuex.Store 本章没有涉及到 Vue.Store 内容,所以隐藏不展示。
*/
export class Store {
xxxxxxx
}
/***
* Vuex.install 不是来自于 Store 类对象,而是一个在 Store.js 文件中单独写的一个函数。
* Vuex 走的第一步,就是这个方法,通过 Vue.use( vuex ) 时,会调用 vuex.install( _Vue ) 方法。
*/
export function install (_Vue) {
//对同一个vue进行重复使用了 vue.use(Vuex), 开发环境内报错误提示。
if (Vue && _Vue === Vue) {
if (__DEV__) {
console.error(
'[vuex] already installed. Vue.use(Vuex) should be called only once.'
)
}
return
}
//在 Vuex.Store 中记录 Vue 类对象。
Vue = _Vue
//在每一个 vue 实例被创建的时候,混合一个 Vuex.Store() 实例。
//对应位置为 ./mixin.js 文件。
applyMixin(Vue)
}
# ======> applyMixin(Vue) 跳转到 /src/mixin.js 文件
Vuex.install 核心方法是 applyMixin(Vue), 指向文件 /src/mixin.js
/**
* Store.js 中 applyMixin(Vue) 对应的方法。
* applyMixin(Vue) =======>
*/
export default function (Vue) {
//获取版本
const version = Number(Vue.version.split('.')[0])
//如果版本是 2.xx 以上,就走 Vue.mixin(xxx) 方法。
if (version >= 2) {
Vue.mixin({ beforeCreate: vuexInit })
} else {
//1.xx 版本时候的处理,可以不看了。
const _init = Vue.prototype._init
Vue.prototype._init = function (options = {}) {
options.init = options.init
? [vuexInit].concat(options.init)
: vuexInit
_init.call(this, options)
}
}
/**
* Vue.mixin({ beforeCreate: vuexInit }) =====>
*/
function vuexInit () {
/** 需要注意的是:
1、此时是在 vue 实例的内部,this指向的是刚创建出来的 vue 实力。所以 this.$options 是指 vue 实例的 options 参数。
2、此时的 vue 的生命周期为 beforeCreate, 也就是说在 created(){} 生命周期的时间内,就可以使用 this.$store 属性了 。
*/
const options = this.$options
//功能: 将 Vuex.Store() 实例在 vue 实例上进行挂在。
//1、先判断当前 vue 实例的 options参数上是否有 store 属性;
// 如果当前 vue 实例的 options参数上的 store 属性是个函数,就调用;否则,就直接赋值给 this.$store.
if (options.store) {
//
this.$store = typeof options.store === 'function'
? options.store()
: options.store
//2、如果当前 vue 实例的 options参数上没有 store 属性;
// 则去查询父组建是否含有 $store 属性,如果有,则获取父组建的 $store。
} else if (options.parent && options.parent.$store) {
//这里为什么不需要逐级往上找了?因为组建创建的过程是一个自顶向下的过程,会将 $store 属性逐步完成从父组建传递到子组件的过程。
this.$store = options.parent.$store
}
}
}