# Vuex 源码解析

# Vuex初始化

Vuex的初始化主要包含两个方面:

  • 1、install(安装过程)
  • 2、Store实例化

# 安装

当我们在代码中通过import Vuex from 'vuex'的时候,实际上引用的是一个对象,它的定义在 src/index.js中:

export default { 
  Store, 
  install, 
  version: '__VERSION__', 
  mapState, 
  mapMutations, 
  mapGetters, 
  mapActions, 
  createNamespacedHelpers 
}
1
2
3
4
5
6
7
8
9
10

和 Vue-Router 一样,Vuex也同样存在一个静态的install方法,它的定义在src/store.js中:

// src/store.js
export function install (_Vue) { 
  if (Vue && _Vue === Vue) { 
    if (process.env.NODE_ENV !== 'production') { 
      console.error( '[vuex] already installed. Vue.use(Vuex) should be called only once.' ) 
    }return 
  }
  Vue = _Vue 
  applyMixin(Vue)
}
1
2
3
4
5
6
7
8
9
10

install 的逻辑其实很简单,把传入的 _Vue 赋值给Vue 并执行 applyMixin(Vue) 方法,它是定义在 src/mixin.js 中:

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. 354
    const _init = Vue.prototype._init 
    Vue.prototype._init = function (options = {}) { 
      options.init = options.init ? [vuexInit].concat(options.init) : vuexInit _init.call(this, options) 
    }
  }
  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 
    } 
  }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

applyMixin 就是这个 export default function 它还兼容了 1.0版本的,我们这里只关注 2.0 以上版本的逻辑,它实际上就是在全局混入了一个 beforeCreate 钩子函数,它的实现非常简单,就是把option.store 保存在所有的组件的 this.$store 中,这个options.store 就是我们在实例化Store 对象的实例。

# Store 实例化

我们在 import Vuex 之后,会实例化其中的Store对象,返回store实例并传入 new Vue 的Options 中,也就是我们刚才提到的 option.store。

举个简单的例子,如下:

export default new Vuex.Store({
  actions, 
  getters, 
  state, 
  mutations, 
  modules // ...
})
1
2
3
4
5
6
7
最后更新时间: 6/19/2021, 10:36:13 AM