Vuex plug-in principle analysis

Vuex is a state management mode developed specifically for vue.js applications. It uses centralized storage to manage the state of all components of an application and rules to ensure that the state changes in a predictable way.

The state self-management application consists of the following parts:

  • State, the data source that drives the application;
  • View, to declaratively map state to the view;
  • Actions, in response to changes in state caused by user input on the view.

Vuex Core Concepts:

  • State is the status and data
  • Use the mutations function to change the state
  • Use actions for asynchronous processing
  • Use getters for further state processing
  • Divide store into modules for modular management

Implement the Store class

  1. When you use new vuex. Store outside, you pass in an object, and the object hasState, mutations, getters, Actions, modulesAnd other object attributes;
  2. inconstructorSave each of these parameter objects passed in as follows:
class Store {
    constructor(options) {
        this._mutations = options.mutations
        this._actions = options.actions
        this._wrappedGetters = options.getters
        this.getters = {}
    }
}
Copy the code
  1. implementationstateThe response of the type

Use new Vue to realize the response

class Store {
    constructor(options){* omit *this._vm = new _Vue({
            data: {
                // Use $$state to prevent direct access to _vm._data
                $$state: options.state,
            },
            computed
        })
    }
    // Get is used here to return a responsive object
    get state() {
        return this._vm._data.$$state
    }
}
Copy the code
  1. implementationgettersresponsive
class Store {
    constructor(options){* omit *this._wrappedGetters = options.getters
        this.getters = {}

        const store = this
        const computed = {}

        // Iterate over each method under the getters object
        Object.keys(this._wrappedGetters).forEach(key= > {
            const fn = store._wrappedGetters[key]
            // Wrap each method under getters in a function and return the result assigned to the calculation property
            computed[key] = function() {
                return fn(store.state)
            }
            // Set the accessor property for the key of store.getters so that it can be accessed through $store.getters.aaa
            // Get the corresponding value on the store instance
            Object.defineProperty(store.getters, key, {
                get: () = > store._vm[key]
            })
        })
    }
}
Copy the code
  1. implementationcommitmethods
commit(type, payload) {
    const mutation = this._mutations[type]
    if(! mutation ||typeofmutation ! = ='function') {
        return new Error('UnKnown is' + type)
    }
    mutation(this.state, payload)
}
Copy the code
  1. implementationdispatchmethods
dispatch(type, payload) {
    const action = this._actions[type]
    if(! action ||typeofaction ! = ='function') {
        return new Error('UnKnown is' + type)
    }
    action(this, payload)
}
Copy the code

Implement the install function

  1. Used to create the current modulelet _VueObject, which is passed in and assigned to _Vue when the install method is called;
  2. installThe function is going to be outsideVue.use(Vuex)Calls to perform
  3. ininstallGlobal mixing in functionsVue.mixinIn thebeforeCreateHook function$store;
  4. The current Vuex instance will be executed earlier than the Vue instance, so we need to make a global mixin mixin, and get the new Vuex.Store instance Store after the execution of new Vue in main.js function is completed, and finally mount it to the Vue prototypeVue.prototype.$store

_Vue, install, $store

function install(Vue) {
    _Vue = Vue

    Vue.mixin({
        beforeCreate() {
            if (this.$options.store) {
                Vue.prototype.$store = this.$options.store
            }
        }
    })
}
Copy the code

Export default {Store,install}