Vuex principle analysis

One, foreword

Since learned VUE framework, including essential use vuex the core plug-in, and when doing the project, basic can use, you might use vuex state management, but there is more or less to vuex principle of doubt or don’t understand, this article will study vuex principle, hope to be able to help you, If there is an inaccurate place, everyone more advice…

What is Vuex?

Vuex is an ecosystem dedicated to Vue to manage the data status of pages and provide unified data operation. It is equivalent to mongoDB, MySQL and other databases. Any component can access the data in the warehouse. Among them, vuex is similar to Redux. Redux is mostly used in React, and Redux will be supplemented later. Now let’s have a good understanding of what Vuex really is.

Conceptual comprehension (must read

Vuex adopts the Model layer of MVC pattern, stipulating that all data must be changed by the process of Action > Mutaion >state. Combined with Vue data view bidirectional binding to achieve page update. Unified page state management makes complex component interactions simpler and clearer, and allows you to view state during debugging using DEVtools.

In the current front-end SPA modular project, it is inevitable that some variables need to be referenced globally. At this time, the transmission of values between parent and child components, the transmission of values between parent and child components, and the transmission of values between sibling components have become the problem we need to solve. Although vue provides props (parent to child) commit (child to parent), siblings can also use localstorage and sessionStorage. But this approach creates more problems in project development than it solves (difficult to manage, difficult to maintain, complex code, low security). Vuex was created to solve these problems and greatly improve the efficiency of our VUE projects.

Throw out problem

To use Vuex, simply execute vue.use (Vuex) and pass in an example store object in the configuration of Vue. How does store implement injection? How is state internally implemented to support module configuration and module nesting? When executing the dispatch action (commit), you only need to pass in (type, payload). Where does the first parameter of the action execution function store come from? How do I distinguish whether state was modified directly externally or by mutation method?Copy the code

3. Relationship between VUE and VUEX

Take a look at this example of vUE responsiveness. Data, methods, computed in VUE can implement responsiveness.

A view can change the value of count in State by clicking on an event that triggers the increment method in Methods. Once the count value changes, a function in computed can update getCount to the view.

<div id="app">
        <button @click="increment"></button>
        {{getcount}}
    </app>
    new Vue({
        el: "#app",
        // state
        data () {
         return {
            count: 0
         }
        },
         // view
        computed: {
            getCount() {return this.count
            }
        },
        // actions
        methods: {
         increment () {
            this.count++
         }
        },
    })
Copy the code

So what does vuex have to do with the reactive example of Vue?

We can use Vuex to achieve the same responsive functionality as VUE.Copy the code

In fact, they work in the same way. Vuex also has four attributes: State, getters, mutations and Actions.

In the absence of actions:

  • State –> data
  • Get data: getters –> computed
  • Change data: mutations –> methods

The view can change the data in state by clicking on an event that triggers the methods in Mutations. Once the state data changes, getters reflects the data to the view.

Actions, then, can be understood to handle asynchrony and simply add another layer.

Now that we’re talking about mutions actions, we have to say commit and dispatch. What does that do?

In the VUE example, methods in Methods are triggered by a click event. When there is asynchrony, and dispatch is required in VUex to trigger methods in Actions, commit in Actions can trigger methods in mutations. Sync, then commit directly in the component triggers the method in VUEX.

Four, vuEX implementation

Let’s take a look at vuex’s ability to change state and update views like vUE’s:

Vuex.js

Const store = new vuex. store ({state: {count: 0}, mutations can only be modified by mutations: { increment(state) { state.count++ } }, //this.$store.commit("increment"Trigger the function in mutations"increment"
    actions: {
        increment({commit}) {
             commit("increment"); //this.$store.commit("increment"Getters: {getCount(state) {getCount(state) {return state.count
        }
    }
    })
     
    export default store

Copy the code

App.vue

    <template>
    <div id="app">
            <button @click="increment"</button> <! Sometimes you can't force the store state this directly.$store.state.count -->
            {{this.$store.getters.getCount}}
    </div>
    </template>
     
    <script>
    export default {
        methods: {
        increment(){
                //this.$store.dispatch("increment"Triggers the Actions function"increment"
                this.$store.dispatch("increment")
            }
        }
    }
    </script>

Copy the code

Five, source code analysis:

Now that we know that Vuex can implement features like vue two-way data binding — update attempts, let’s focus on the implementation of vuex source code:

5.1 store Inject component install method

Answer: How is vuex’s Store injected into a component?

To start with Vuex, you need to install the plug-in:

Vue.use(Vuex); // Vue plug-in mechanism, install vuex plug-inCopy the code

When ues(Vuex) is installed, the install method in Vuex is invoked. The following is the core source of Install:

Vue.mixin({
        beforeCreate() {
            if (this.$options && this.$options.store) {// Find the root component main to hang one on$store
                this.$store = this.$options.store
                // console.log(this.$store);

            } else{// the non-root component points to its parent$store
                this.$store = this.$parent && this.$parent.$store}}})Copy the code

Store can inject vUE instance components by using vUE mixin mechanism and vUE component lifecycle hook beforeCreate. During each VUE component instantiation, the vuexInit method is called in front of the beforeCreate hook.

Answer: How do vuex’s state and getters map to responsive update state in each component instance?

5.2 New Vue implements bidirectional data binding:

This. _s = new Vue({data: {// only data in data is responsive state: options.state}})Copy the code

5.3 getters implementation

// Implement the getters principleletgetters = options.getters || {} // console.log(getters); // this.getters = getters; Getters = {}; this.getters = {}; // console.log(Object.keys(getters)) // ["myAge"."myName"ForEach ((getterName) => {// console.log(getterName) // myAge // put getterName in this.getters = {}  // console.log(this.state); Object.defineproperty (this.getters, getterName, {// When you want to get getterName (myAge), the get method is automatically called // Arrow function does not have this get: () => {return getters[getterName](this.state)
                }
            })
        })
Copy the code

From the above source code, we can see that the state of Vuex is responsive, and vue’s data is responsive. The state is stored in the data of vUE instance components. Vuex’s getters realize real-time data monitoring through computed property of VUE.

5.4. Mutations are realized


let mutations = options.mutations || {}
        // console.log(mutations);
        this.mutations = {};
        Object.keys(mutations).forEach(mutationName=>{
            // console.log(mutationName);
            
            this.mutations[mutationName] = (payload) =>{
                this.mutations[mutationName](this.state,payload)
            }
        })
Copy the code

Realize synchronous add: dynamic renderings:

5.5 actions implementation

// How actions worklet actions = options.actions || {}
        this.actions = {};
        forEach(actions,(actionName,value)=>{
            this.actions[actionName] = (payload)=>{
                value(this,payload)
            }
        })
Copy the code

5.6. Implementation of Commit Dispatch

    commit(type,payload){
        this.mutations[type](payload)
    }
Copy the code
    // typeIs the type of actions dispatch=(type,payload)=>{
        this.actions[type](payload)
    }
Copy the code

Six, principle summary:

Vuex implements state sharing among components by globally injecting store objects. Vuex is suitable for large and complex projects (multi-level component nesting) where one component needs to change some data and multiple components automatically acquire the changed data for business logic processing. Using Vuex is a bit overkill if you’re just passing data between components. You can just use the usual communication methods between components.

Additional reference vuex source code, can be debugged

Refer to the link: www.cnblogs.com/hjson/p/105…

Common interview: blog.csdn.net/xu838209490…