How to use Vuex
While everyone is familiar with how to use Vuex, let’s briefly review the source code before looking at how to register the Store.
-
NPM install vuex –save
-
Create a store directory under the SRC directory in your vue project and create a new file — index.js under this directory to create the Store instance.
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex) // Install Vuex plug-in
const state = {}
const mutations = {}
const actions = {}
const getters = {}
// Create a store instance object and export it. Just for example, some empty objects are defined.
export default new Vuex.Store({
state,
mutations,
actions,
getters
})
Copy the code
- In the main.js entry file
import Vue from 'vue'
import App from './App.vue'
import store from './index'
new Vue({
el: '#app'.// Provide the store object to the "store" option, which injects store instances into all child components
store,
render: h= > h(App)
})
Copy the code
After reviewing, we all have the impression inevitably, next step into the main topic.
Registered store
Those of you who have used Vuex know that Vuex provides a mechanism to “inject” state from the root component into each child component through the Store option (call vue.use (Vuex)). By registering the Store option in the root instance, the store instance is injected into all the children of the root component, which can be accessed through this.$store.
To understand how this works, we need to understand vue.use.
Vue. Use definition
Quoted from the official definition:
Install vue.js plug-in. If the plug-in is an object, the install method must be provided. If the plug-in were a function, it would be used as the install method. When the install method is called, Vue is passed in as an argument.
This method needs to be called before calling new Vue(). When the install method is called multiple times by the same plug-in, the plug-in will only be installed once.
From the above definition, it is not difficult to understand. To install a Vue plug-in, the plug-in must either provide the install method or be a function itself. So, when we install the Vuex plug-in using vue.use (Vuex), we are actually calling its internal install method.
Vue. Use method
Vue.use is a method defined in the Vue source code that is used to install Vue plug-ins.
export function initUse (Vue: GlobalAPI) {
// plugin is an object or function
Vue.use = function (plugin: Function | Object) {
// Define an array variable to store the plug-in
const installedPlugins = (this._installedPlugins || (this._installedPlugins =
[]))
// Determine if vue has registered the plugin
if (installedPlugins.indexOf(plugin) > -1) {
return this
}
// toArray is a utility method defined in the vue source code
// toArray(arguments, 1) converts arguments to an array and returns arguments
// All parameters except the first one (i.e. the plug-in plugin) are stored in an array.
const args = toArray(arguments.1)
// Insert the vUE object into the first part of the ARGS array
args.unshift(this)
// Determine whether the plug-in has an install method.
// If so, call the install method and pass in the parameters array, changing the this pointer to the component
// If not, change this pointer to null
if (typeof plugin.install === 'function') {
plugin.install.apply(plugin, args)
} else if (typeof plugin === 'function') {
plugin.apply(null, args)
}
// Add plugin to the installedPlugins array to check if the plugin has been installed
installedPlugins.push(plugin)
return this}}Copy the code
ToArray method
ToArray is a utility method defined in the vue source code.
// Convert an array-like object into a real array
export function toArray (list: any, start? : number) :Array<any> {
start = start || 0
let i = list.length - start
const ret: Array<any> = new Array(i)
while (i--) {
ret[i] = list[i + start]
}
return ret
}
Copy the code
Use calls its install method if it is ‘object’, and calls itself as install if it is ‘function’. Now that you’ve sorted out the vue. use source code implementation, the next step is to expose the install method in Vuex source code.
Vuex the install
The core of the Install method is to call the applyMixin method.
// The file path in Vuex is SRC /store.js
export function install(_Vue) {
// Avoid repeated installation
if (Vue && _Vue === Vue) {
if (__DEV__) {
console.error(
// The vuex is already installed. Vue.use(Vuex) should only be called once.
'[vuex] already installed. Vue.use(Vuex) should be called only once.')}return
}
// For the first load, assign the _Vue variable to Vue and use it to detect duplicate installation
Vue = _Vue
// applyMixin is the key to injecting store instances into all children of the root component
applyMixin(Vue)
}
Copy the code
applyMixin
ApplyMixin, which actually implements the method of injecting store instances into all children of the root component. The vue1.0 and 2.0 versions are treated differently.
// The file path in Vuex is SRC /mixin.js
export default function (Vue) {
const version = Number(Vue.version.split('. ') [0]) // Get the vUE version number
if (version >= 2) {
// Vue. Mixin globally registers a mixin, affecting all Vue instances created after registration.
Plugin authors can use mixin to inject custom behavior into components. Not recommended for use in application code.
// blend vuexInit into Vue's beforeCreacte hook.
// The vuexInit method is executed on each Vue instance.
Vue.mixin({
beforeCreate: vuexInit
})
} else {
// Override initialization and inject the vuEX initialization process
const _init = Vue.prototype._init
Vue.prototype._init = function (options = {}) {
options.init = options.init ? [vuexInit].concat(options.init) : vuexInit
_init.call(this, options)
}
}
Vuex initializes hooks, injected into each instance's initializing hook list
function vuexInit() {
const options = this.$options
// store injection. If options.store exists, the current component is the root component, otherwise it is a child component
if (options.store) {
this.$store = typeof options.store === 'function' ?
options.store() : options.store
} else if (options.parent && options.parent.$store) {
// The child refers to $store in its parent. Thus, pass this.$store in any component
// Access the store of the root instance
this.$store = options.parent.$store
}
}
}
Copy the code
conclusion
For parsing source code this kind of thing, I am also a novice on the road. If there is something wrong or not precise, I hope my friends can point it out so that we can happily lose our hair together. At the same time, it is recommended that beginners have learned and used Vuex before reading the source code. Only in this way can we have a clearer understanding of its workflow and principles.