This is the 8th day of my participation in Gwen Challenge
Original TANGJIE Vue2 Vuex
The basic principle of VuEX & Simple handwriting vuex
To write a simple VUex, you must first know what vuex is, what the design goal is, and how it is used. Only in this way can we be stronger standing on the shoulders of giants.
1. Basic concepts of Vuex
Vuex is a repository that centrally manages and stores the state of all components of an application, with rules to ensure that state changes in predictable ways
1.1 Basic Concepts
- State and data
- Mutations, the word mutations means change, a function that changes state
- Actions Asynchronous behavior
- Store contains the container of the above concepts
1.2 Basic Usage
First picture:
In fact, it is very simple to use:
- Create a store directory under SRC to store the vuex code files (I like vuex modules under various routing components), and write state, mutations, actions, etc
import Vue from 'vue'
import Vuex from 'vuex'
import modelone from './modelone'
Vue.use(Vuex)
export default new Vuex.Store({
state: {
name:'test',},mutations: { // Synchronize methods
setName(state,proload){
state.name = proload
}
},
actions: {
launchSetName(ctx,proload){ // Asynchronous method
// Change after 2 seconds
setTimeout(() = >{
ctx.commit('setName',proload)
},2000)}},modules: {
modelone
}
})
Copy the code
- Use under components (basic use)
.// Get the value of state directly in store
this.$store.state.name
...
methods: {// Use mutation directly
changeStateName(){
this.$store.commit('setName'.'Xiao Ming has a crush on Xiao Hong')},// Use action directly
afterSecondsChangeName(){
this.$store.dispatch('launchSetName'.'Two seconds later Red ran away.')}}...Copy the code
See here compared to the above figure, is not a sudden clear up, the original use is so simple ~
- Component under use (use
vuex
Give themapXXX
To use)
.computed: {// Map the property value of state. mapState({name:state= > state.name
})
},
methods: {// use mutation in map mode. mapMutations({changeMapStateName: 'setName'
}),
// Map uses action. mapActions({launchSetName:'launchSetName'})}...Copy the code
1.3 Thinking about vuEX usage scenarios
While vuEX is comfortable with state sharing across hierarchies, maintenance, code migration, and more can be cumbersome. Personally, it is not appropriate to store too many state attributes in Vuex. For global attributes of routing components, provide/ Inject is more silkier than Vuex.
However, in many development practices, the data of back-end asynchronous request are included in VUEX state management, and the logic of adding, deleting, modifying and checking data is encapsulated in Action. In this way, the front-end logic code can be layered to a certain extent, so that the code in the component pays more attention to the logic of the view layer such as page interaction and data rendering. I have reservations about vuex managing vUE for asynchronous requests, persistence of state data, etc. Back-end API management can be managed by a separate API file. Keep-alive is a better choice for persistence of background data
Up to now, I think the biggest role of VUEX is in SSR. (Personal opinion)
2. Develop a simple Vuex
Through the above understanding of the basic concept of VUEX and the use of VUEX, start from the perspective of use, a simple VUEX development. So that we can have a deeper and thorough understanding of VUEX
2.1 The first step is to create an install method
In this install method, to implement the Store instance and mount it to Vue prototype, Use (vuex.store) occurs before or after new Store(). In order to ensure that an instance of Store can be obtained, it is generally handled as follows
const install = ( Vue ) = >{
vueComponent = Vue;
Vue.mixin({
beforeCreate(){
if(this.$options.store){
Vue.prototype.$store = this.$options.store
}
}
})
}
Copy the code
Some of you might have questions here, right? This.$options.store = Vuex; this.$options.store = Vuex
.new Vue({
router,
store,
render: h= > h(App)
}).$mount('#app')...Copy the code
From the above code we can clearly see that the instantiated Store is directly new Vue(…). Vue. Mixin is mixed into all Vue instances, but only Store instances are initialized. Vue.
2.2 Building the Store class
From a Vuex usage point of view, building a Store class is easy
class Store{
constructor( options ){
// Create the Store state property, because state is reactive and therefore reactive
this.state = options.state
vueComponent.observable(this.state);
// Create the Store actions property
this.actions = options.actions
// Open the mutations attribute of the Store
this.mutations = options.mutations
/ / bind this
this.commit.bind(this);
this.dispatch.bind(this);
}
commit(){}
dispatch(){}}Copy the code
2.3 establishcommit
Methods the function
According to mutations,commit takes two parameters, one is the mutation attribute name under Store and the other is the payload parameter, and then triggers the function on mutations. There is the following code for this
.commit(type,payload){
if( this.mutations[type] ){
this.mutations[type](payload)
}
}
...
Copy the code
Actions is similar to mutation!
2.4 Complete Code
let vueComponent;
class Store {
constructor( options ){
console.log( this === Store.constructor,this ,'this')
this.mutations = options.mutations;
this.actions = options.actions;
this.state = options.state;
// Bind this, the context always points to the store instance
this.commit.bind( this );
this.dispatch.bind( this );
// make state reactive
vueComponent.observable(this.state);
}
commit(type,payload){
const entry = this.mutations[type];
if(entry){
entry(this.state,payload)
}
}
dispatch(type,payload){
const entry = this.actions[type];
if(entry){
entry(this,payload)
}
}
}
const install = ( Vue ) = >{
vueComponent = Vue;
Vue.mixin({
beforeCreate(){
if(this.$options.store){
// Mount store to the vue prototype
// This is because the Vue plugin is used in Vue. Use
Use tends to occur faster than Store instantiation
// Therefore, the lifecycle is needed to ensure that the Store instance is retrieved
Vue.prototype.$store = this.$options.store
}
}
})
}
export default{
Store,
install
};
Copy the code