preface
Through B station video and some children’s shoes article combined with Git source reading to understand the principle of vuEX implementation
Say no more, we directly on the source code
Vuex SRC directory
First take a look at vuex’s source directory. As you know, major projects are usually under SRC, so we’ll start directly from there
- Module: Module constructor and module collection management
- You can debug dvTools by using your plugins
- Helpers: Integrated grammar sugar
mapState, mapMutations, mapGetters, mapActions, createNamespacedHelpers
- Index: import file, export store, install, and above syntax sugar ↑
- Mixin: Mixin, initialize vuex, and mount the Vue root instance
- Store: the vuex constructor, which implements the main function of the function
- Utils: Some tool methods
Okay, so that’s basically what this is; As we know from the official documentation, every vUE plug-in needs to have a public install method, and vuex is no exception. Step by step we analyze
Vuex entrance
src/index.js
// Import and initialize install
import { Store, install } from './store'
// ES6 extends syntax
import { mapState, mapMutations, mapGetters, mapActions, createNamespacedHelpers } from './helpers'
/ / export
export default {
Store,
install,
version: '__VERSION__',
mapState,
mapMutations,
mapGetters,
mapActions,
createNamespacedHelpers
}
Copy the code
Vue. Use (plugin), Vue. Use (), Vue. Use (), Vue. It also executes the public install method of the plug-in by default (see the official website). Ok, go to Install initialization
Vuex install method
SRC /store.js 523 lines of store.js code is a lot of code, I did not comb through the line by line, here select some important points for analysis
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
SRC /store.js (); /* constructor (); Vue && typeof window ! == 'undefined' && window.vue) {install(window.vue) // pass Vue root instance to install} */
applyMixin(Vue)
}
Copy the code
Mixed with Vuex
Ok, to follow the lead, let’s go to the applyMixin method at SRC /mixins.js
export default function (Vue) {
// Depending on the version
const version = Number(Vue.version.split('. ') [0])
if (version >= 2) {
Vue.mixin({ beforeCreate: vuexInit }) // Life cycle created before mixing mount vuex
} else {
const _init = Vue.prototype._init // Mount on the root instance
Vue.prototype._init = function (options = {}) {
options.init = options.init
? [vuexInit].concat(options.init)
: vuexInit
_init.call(this, options)
}
}
// Initialize the vuex method
function vuexInit () {
const options = this.$options
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
Examples of evolution
After initialization, let’s take a look at how vuex is used in daily development
import Vue from 'vue' // Import the vue instance
import Vuex from 'vuex' // Import state management vuex
Vue.use(Vuex) // Install and initialize vuex
const store = new Vuex.Store({ / / use
state: {},// The location where the state is stored
getters: {},// Get the status
mutations: {},// Define the only way to synchronously modify the state
actions: {},// Commit a mutaions where the state is asynchronously modified
modules: {}// Module distribution
});
Copy the code
The store constructor initializes and integrates the corresponding properties and methods, respectively.
Initialization declaration within Store Constructor
// Initialize some parameters
this._committing = false // Whether the status identifier is being submitted
this._actions = Object.create(null) // Create acitons
this._actionSubscribers = [] // Action subscription list
this._mutations = Object.create(null) // Create mutations operation object
this._wrappedGetters = Object.create(null) // Create the getters collection object
this._modules = new ModuleCollection(options) // Vuex supports store-incoming modules to store analyzed modules
this._modulesNamespaceMap = Object.create(null) // Create the module namespace map
this._subscribers = [] // Subscribe to the collection of functions
this._watcherVM = new Vue() // The Vue component is used for watch to monitor changes
// Replace the dispatch, commit methods in this to point this to store
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)
}
/ / state tree
this.strict = strict
// Initialize the module
const state = this._modules.root.state
// Initialize the module
installModule(this, state, [], this._modules.root)
// Reset the virtual VM
resetStoreVM(this, state) // Key, key, key, the whole vuEX function implementation method
// Load the plugins in turn
plugins.forEach(plugin= > plugin(this))
// Debug tool
if (Vue.config.devtools) {
devtoolPlugin(this)}Copy the code
Vuex core
ResetStoreVM Resets the Store instance
function resetStoreVM (store, state, hot) {
const oldVm = store._vm // Copy the old instance
store.getters = {} // Set the getters property
const wrappedGetters = store._wrappedGetters // Store the getters collection object
const computed = {}
// Run through the object wrappedGetters
forEachValue(wrappedGetters, (fn, key) = > {
// Add getter object properties for a computed object
// Store.getters. Xx = store._vm[xx]; // Store.getters.
// Add attributes in the getter for computed to facilitate the new vUE instance for store._vm
computed[key] = partial(fn, store)
/* export function partial (fn, arg) { return function () { return fn(arg) } } */
// Override the get method for each getters object to create an observation
Object.defineProperty(store.getters, key, {
get: () = > store._vm[key],
enumerable: true // for local getters})})// Create an instance of Vue to hold the state and make the state responsive, the same principle as the Vue component
// store._vm._data.$$state = store.state
store._vm = new Vue({
data: {
$$state: state
},
computed // Calculates properties for each property method in the wrappedGetters (getter collection object) above
})
// You can change the state only by committing
if (store.strict) {
enableStrictMode(store)
}
}
Copy the code
conclusion
The state state of Vuex is responsive, and the state is stored in the data of the new VUE instance component by means of the data of VUE is responsive. Vuex getters realize real-time data monitoring with the help of VUE’s computing attribute computed.
Full source interpretation: reference
The Store in Vuex is essentially a Vue component without a template
Welcome to like, a little encouragement, a lot of growth
A link to the
- Front-end visualization platform implementation scheme
- Vue3 10 minutes takes you seconds to vue3
- Vue template compilation principle
- The vue constructor extends
- How does VUEX state management work
- Vue-router source analysis principle
- Vue [how to listen for array changes]
- Handwritten Vue response [object.defineProperty]
- Vue responsive source sharing