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.