Vuex source reading and analysis

Keywords: Javascript Vue Windows

I. how Vuex is injected into Vue

Mount $store to the prototype chain of vue when beforeCreate is executed.

let Vue;

function install(vm,storeName='$store'){
    Vue = vm;
    Vue.mixin({
        beforeCreate() {
            if(this.$options.store){
                //Mount $store to Vue's prototype
                Vue.prototype[storeName] = this.$options.store;
            }
        }
    })
}

II. How Vuex realizes state responsive core

In essence, it adopts the data response principle of Vue.

//Registered state
const store = new vuex.Store({
    state:{
        inputText:''
    },
    ......
});
//Map state to data in Vue instance when new vuex.Store
class Store{    
    constructor(options={}){
        this.state = new Vue({
            data:options.state
        })
    }
    .....
}

Three, getter

The function of getter is to calculate and process the state, similar to the calculated property of vue. The principle of getter is to use the getter of Object.defineProperty hijacking property to save the calculated result in the getter of vuex.

registerGetter(getters){
    this.getters = {}
    let vm = this.state;
    for (const key in getters) {
        if (getters.hasOwnProperty(key)) {
            Object.defineProperty(this.getters,key,{
                get(){
                    //Call the function of getter in the vuex parameter and cache the result in the getter
                    return getters[key](vm);
                }
            })
        }
    }
}

IV. how to update status

1. Register the mutations function

const store = new vuex.Store({
    state:{
        inputText:''
    },
    mutations:{
        /**The state here is actually an instance of vue */
        updateInputText(state,payload){
            state.inputText = payload;
        }
    }
});

2. To change the state, the commit function must be triggered. The commit function calls the functions in mutaions, and transfers the vue instance and the data to be changed to the mutations function.

commit(m_name,payload){
    const fn = this.mutations[m_name];
    fn(this.state,payload);
}

3. Why must mutations be asynchronous?

If it is asynchronous, it will make debugging of devtool difficult, and it is difficult to track the change of state.

Five, action

1. Action is similar to mutation. The difference is that: the submitted action is mutation; action can be asynchronous, but mutation can only be synchronous.
2. Register actions

const store = new vuex.Store({
    state:{
        inputText:''
    },
    mutations:{
        updateInputText(state,payload){
            state.inputText = payload;
        }
    },
    actions:{
        text({commit}){
            //Simulate an asynchronous operation
            setTimeout(() => {
                commit('updateInputText')
            }, 1000);
        }
    }
});

3. To distribute an action, the dispatch method must be triggered. The dispatch function passes commit/state/getters to the action function.

dispatch(a_name,arg){
    //Source code uses promise for asynchronous processing here
    const fn = this.actions[a_name];
    fn({
        commit:this.commit,
        state:this.state,
        getters:this.getters
    },arg);
}

4. Why do I need action for asynchronous management?
Scenario: if there are two asynchronous operations A and B, they all operate on the same mutation, and B needs to submit after A submits the mutation.
When there is such a complex operation, you need to use action to deal with the asynchronous problem.

actions: {
  // ...
  actionB ({ dispatch, commit }) {
    return dispatch('actionA').then(() => {
      commit('someOtherMutation')
    })
  }
}

6. Common plug-ins

1. Vuex persistent state uses the local storage of the browser to persist the state. This means that refreshing the page or closing the tabs will not delete your data.
2. Vuex shared animations can synchronize different tabs. It stores the state to the local storage through Mution. When the contents in the tabs and windows are updated, the save event is triggered, and the mutation is called again to keep the status synchronized.
3. vuex-i18n allows you to easily store content in multiple languages. Make it easier for your app to switch languages.
4. Vuex loading helps you manage multiple loading states in your application. This plug-in is suitable for real-time applications with frequent and complex state changes.
5. Vuex cache can cache the action of vuex. For example, if you retrieve data from the server, the plug-in caches the results the first time the action is called, and then directly returns the cached value in the subsequent dispatch. It's also easy to clear the cache if necessary.

Reference articles

https://www.cnblogs.com/haishen/p/11315669.html

Posted by igoy on Mon, 21 Oct 2019 21:44:32 -0700