I. VuEX initialization
When you import Vuex from ‘Vuex, you will find the module in package.json (dist/vuex.esm.js). Vuex and vue-Router are the same as vue and are built by rollup. NPM run build:main (node scripts/build-main.js) is executed with rollup.main.config.js. In rollup.main.config.js, the input is SRC /index.js and the file is dist/vuex.esm.js. In other words, the main entry of vuex is SRC /index.js. Use (Vuex) is used to register the plug-in. When analyzing vue-Router, we can know that vue. use will actually execute the install method from the plug-in export. Vuex’s install method determines whether the globally defined Vue exists and is equal to the parameter Vue passed by install. If it is the same, the vuex method terminates the function execution. This is to prevent multiple uses and ensure that only one is executed, just like vue-router. If it is the first use, the global Vue is assigned to the incoming Vue and applyMixin(Vue) is executed. Vuex is mounted by overwriting vue.prototype. _init if the vuex version is less than 2 and passing vuex as an argument to init. Vue.mixin is mounted by overwriting vue.prototype. _init if the vuex version is greater than or equal to 2. The vuexInit function is used as the execution function for the beforeCreate life cycle. This.$options.store gets the store passed in when new Vue(). If the store is a root instance, the vuexInit function checks whether the store is a function. It will execute and assign to this.$store, or if it is not a function, it will assign directly. $store = this.$options. Parent.$store = this.$options.parent. This ensures that anywhere in the world we can access the store instance through this.$store. $store = $store = $store = $store = $store = $store = $store = $store = $store = $store = $store = $store = $store
// 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.
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
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
}
}
}
Copy the code
Store constructor is performed when new vuex.store () is executed. If yes, vuex is not imported via NPM, but via external chain. Then install(window.vue) will be executed. Call Install once to mount vuex. He then determines whether there is a global Vue, if not, that vuex was not properly registered with use before the New Store instance (the global Vue is assigned in the install method), and whether there are promises, indicating that vuex relies on promises. Finally, check whether this, the current instance, is constructed by Store. If it is not, it means that the new operator is not used to construct vuex instances, but Store is directly called. You define private variables (_research, _actions, _modules). We then take dispatch and commit out of this and change their this pointer with a call, so that if the user tries to change their this pointer with a call, their this will still point to the store instance when it was created. State is created, installModule is called to initialize the root module, all sub-modules are registered, and getters for all modules are collected to this._wrappedGetters, resetStoreVM is called, Makes the store responsive, and also registers _wrappedGetters to make it a computed.
export class Store {
constructor (options = {}) {
// Auto install if it is not done yet and `window` has `Vue`.
// To allow users to avoid auto-installation in some cases,
// this code should be placed here. See #731
if(! Vue &&typeof window! = ='undefined' && window.Vue) {
install(window.Vue)
}
if (__DEV__) {
assert(Vue, `must call Vue.use(Vuex) before creating a store instance.`)
assert(typeof Promise! = ='undefined'.`vuex requires a Promise polyfill in this browser.`)
assert(this instanceof Store, `store must be called with the new operator.`)}const {
plugins = [],
strict = false
} = options
// store internal state
this._committing = false
this._actions = Object.create(null)
this._actionSubscribers = []
this._mutations = Object.create(null)
this._wrappedGetters = Object.create(null)
this._modules = new ModuleCollection(options)
this._modulesNamespaceMap = Object.create(null)
this._subscribers = []
this._watcherVM = new Vue()
this._makeLocalGettersCache = Object.create(null)
// bind commit and dispatch to self
const store = this
const { dispatch, commit } = this
this.dispatch = function boundDispatch (type, payload) {
return dispatch.call(store, type, payload)
}
this.commit = function boundCommit (type, payload, options) {
return commit.call(store, type, payload, options)
}
// strict mode
this.strict = strict
const state = this._modules.root.state
// init root module.
// this also recursively registers all sub-modules
// and collects all module getters inside this._wrappedGetters
installModule(this, state, [], this._modules.root)
// initialize the store vm, which is responsible for the reactivity
// (also registers _wrappedGetters as computed properties)
resetStoreVM(this, state) ... }}Copy the code