Vuex 源码解析5 (index.js , index.esm.js, mixin.js)
一. index.js
import { Store, install } from './store'
import { mapState, mapMutations, mapGetters, mapActions, createNamespacedHelpers } from './helpers'
// 导出vuex 相关api
export default {
Store,
install,
version: '__VERSION__',
mapState,
mapMutations,
mapGetters,
mapActions,
createNamespacedHelpers
}
二. index.esm.js
import { Store, install } from './store'
import { mapState, mapMutations, mapGetters, mapActions, createNamespacedHelpers } from './helpers'
// 默认导出vuex
export default {
Store,
install,
version: '__VERSION__',
mapState,
mapMutations,
mapGetters,
mapActions,
createNamespacedHelpers
}
// 多了一种导出方式
export {
Store,
install,
mapState,
mapMutations,
mapGetters,
mapActions,
createNamespacedHelpers
}
另个源码文件比较简单没有什么太多好讲的。 这里说说两个文件的区别:
(1) index.esm.js 比 index.js 多了一个导出模式
(2) import Vuex from 'index.js' : 只有一种方式导出
(3) import Vuex, { mapState } frm 'index.esm.js' : 有两种方式导
三. mixin.js
export default function (Vue) {
/*获取Vue版本,鉴别Vue1.0还是Vue2.0*/
const version = Number(Vue.version.split('.')[0])
if (version >= 2) {
/*通过mixin将vuexInit混淆到Vue实例的beforeCreate钩子中*/
Vue.mixin({ beforeCreate: vuexInit })
} else {
// override init and inject vuex init procedure
// for 1.x backwards compatibility.
/*将vuexInit放入_init中调用*/
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.
*/
/*Vuex的init钩子,会存入每一个Vue实例等钩子列表*/
function vuexInit () {
const options = this.$options
// store 注入
if (options.store) {
/*存在store其实代表的就是Root节点,直接执行store(function时)或者使用store(非function)*/
this.$store = typeof options.store === 'function'
? options.store()
: options.store
} else if (options.parent && options.parent.$store) {
/*子组件直接从父组件中获取$store,这样就保证了所有组件都公用了全局的同一份store*/
this.$store = options.parent.$store
}
}
}
该文件作用是在Vue的生命周期的初始化(<2.0版本是init, >=2.0是beforeCreated)钩子前插入一段Vuex初始化代码。 做的事情就是给Vue 实例注入一个$state的属性。