0
点赞
收藏
分享

微信扫一扫

vuex3.0源码解读系列 第一步:vue.use(Vuex) 挂载$store流程

正义的杰克船长 2022-03-12 阅读 46

通过 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
    }
  }
}

举报

相关推荐

0 条评论