First look vuex Source directory
The source code is all in the src directory, and the entry file is index.js (or index. ESM. JS). When importing vuex from 'vuex', the entry is index.esm.js(esm: es6 module). Look inside
import { Store, install } from './store' import { mapState, mapMutations, mapGetters, mapActions, createNamespacedHelpers } from './helpers' export default { Store, install, version: '__VERSION__', mapState, mapMutations, mapGetters, mapActions, createNamespacedHelpers } export { Store, install, mapState, mapMutations, mapGetters, mapActions, createNamespacedHelpers }
The first step is to introduce the Store and install. First, look at the install method
export function install (_Vue) { // Vue already exists and is equal, which means that Vuex has been install ed if (Vue && _Vue === Vue) { // Error is reported in non production environment. vuex has been installed and the code continues to execute if (process.env.NODE_ENV !== 'production') { console.error( '[vuex] already installed. Vue.use(Vuex) should be called only once.' ) } return } Vue = _Vue applyMixin(Vue) }
The above code logic is very simple. When executing Vuex.install, the Vue constructor is passed in, and then applyMixin(Vue) is executed
However, after we introduce Vuex, we usually execute Vue.use(vuex)
import Vue from 'vue' import Vuex from 'vuex' Vue.use(Vuex)
Take a look at the vue source code
// src/core/global-api/use.js /* @flow */ import { toArray } from '../util/index' export function initUse (Vue: GlobalAPI) { Vue.use = function (plugin: Function | Object) { const installedPlugins = (this._installedPlugins || (this._installedPlugins = [])) if (installedPlugins.indexOf(plugin) > -1) { return this } // additional parameters const args = toArray(arguments, 1) args.unshift(this) if (typeof plugin.install === 'function') { plugin.install.apply(plugin, args) } else if (typeof plugin === 'function') { plugin.apply(null, args) } installedPlugins.push(plugin) return this } }
If the plugin passed in has the install method, execute the install method. Of course, we can also directly hit the direct install method. The effect is the same
import Vue from 'vue' import Vuex from 'vuex' Vuex.install(Vue)
Take a look at the applyMixin method, which is in mixin.js
// vuex/src/minx.js export default function (Vue) { const version = Number(Vue.version.split('.')[0]) // 2 if (version >= 2) { // A beforeCreate hook function is mixed into the global 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 // Make each Vue instance have the $Store object (Store instance, which contains a series of methods and properties), and it is the same object. // First, judge options.store, that's it // 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 } } }
Take a look at the Vue.mixin method in Vue's source code
// src/core/global-api/mixin.js /* @flow */ import { mergeOptions } from '../util/index' export function initMixin (Vue: GlobalAPI) { Vue.mixin = function (mixin: Object) { this.options = mergeOptions(this.options, mixin) return this } }
In fact, a beforeCreate hook function is mixed in the whole world to print the Vue instance