1. What does Vuex do?
Official explanation: Vuex is a state management mode developed specifically for Vue.js applications. It uses centralized storage management
- The state of all components of the application, and the corresponding rules ensure that the state changes in a predictable manner.
- Vuex is also integrated into Vue's official debugging tool devtools extension, providing advanced debugging functions such as zero-configuration time-travel debugging, state snapshot import and export, and so on.
What exactly is state management?
- The terms state management mode and centralized storage management sound very tall and unpredictable.
In fact, you can simply think of it as storing all the variables that need to be shared by multiple components in one object. - Then, put this object in the top-level Vue instance so that other components can use it.
So, can multiple components share all variable properties in this object?
- Wait, if that's the case, why does the official release a special plug-in Vuex? Can't we encapsulate an object to manage it ourselves?
- Of course, we just have to think about the greatest convenience that VueJS brings us? Yes, it is responsive.
- If you encapsulate and implement an object yourself, can you guarantee that all the properties in it are responsive? Of course, you can, but it may be a little troublesome to encapsulate it yourself.
- Needless to say, Vuex is just to provide such a plug-in that shares state among multiple components, just use it.
Second, what state is it managed?
But what state should we share among multiple components?
- If you have done a large-scale opening, you must have encountered multiple statuses, sharing issues between multiple interfaces.
- For example, the user's login status, user name, avatar, geographic location information, and so on.
- For example, the collection of goods, the items in the shopping cart, and so on.
- These status information, we can all put it in a unified place to save and manage it, and they are still responsive (we can see the code later, don’t worry).
OK, after understanding state management in theory, let us look at state management from the actual code.
After all, Talk is cheap, Show me the code. (from Linus)
Let's take a look at the state management of the interface first.
Three, single interface status management
We know that state management in a single component is a very simple thing.
What does it mean? Let's take a look at the picture below.
How do you understand the three things in this picture?
- State: Needless to say, it is our state. (You can treat it as an attribute in data for the time being)
- View: View layer, which can display different information in response to changes in State. (Is this easy to understand?)
- Actions: The Actions here are mainly various actions of the user: click, input, etc., which will cause the state to change.
Write some code to deepen your understanding:
look at the code effect on the right, surely it will be achieved, right?
In this case, do we have some state to manage? That's right, it's just the number of counters.
- The counter needs to be recorded in some way, which is our State.
- The current value of counter needs to be displayed in the interface, which is our View part.
- When certain operations occur on the interface (we are the user’s click here or the user’s input), we need to update the status, which is our Actions
- Isn't this the flow chart above?
4. Multi-interface status management
Vue has helped us manage the state of a single interface, but what about multiple interfaces?
- Multiple views depend on the same state (a state is changed, and multiple interfaces need to be updated)
- Actions of different interfaces want to modify the same state (Home.vue needs to be modified, and Profile.vue also needs to modify this state)
That is to say, for some states (state1/state2/state3), it only belongs to one of our views, but there are also some states (state a/state b/state c) that belong to multiple attempts to maintain together.
- State 1 / State 2 / State 3 You put it in your own room, you manage and use it yourself, no problem.
- But state a/state b/state c we hope to hand over to a big housekeeper to help us manage it in a unified way! ! !
- That's right, Vuex is to provide us with the tool of this big housekeeper.
Global singleton mode (big butler)
- What we have to do now is to extract the shared state and give it to our steward for unified management.
- After that, each of your views will be accessed and modified in accordance with the rules I have prescribed.
- This is the basic idea behind Vuex.
Vuex state management legend:
Fourth, the basic use of Vuex
Let's implement the simple case before
- First, we need to store our Vuex code somewhere:
Here, we first create a folder store, and create an index.js file
in it. Write the following code in the index.js file:
- Mount to the Vue instance.
Secondly, we make all Vue components can use this store object.
Go to the main.js file, import the store object, and put it in new Vue. In
this way, in other Vue components, we can pass itthis.$store
. Way, get the store object
- Use Vuex's count
Okay, this is the easiest way to use Vuex.
Let's make a simple section on the steps of use:
- Extract a common store object to save the state shared among multiple components
- Place the store object in the new Vue object so that it can be used in all components
- Use store object stored in the state to other components
bythis.$store.state.属性
way of the access state
bythis.$store.commit('mutation中方法')
modifying the state
Precautions:
- We submit the mutation instead of directly changing it
store.state.count
. - This is because Vuex can track state changes more clearly, so don't change
store.state.count
the value directly .
Five, Vuex core concepts
Vuex has several core concepts:
- State
- Getters
- Mutation
- Action
- Module
we will introduce it one by one.
5.1 State single state tree
Vuex proposes to use a single state tree. What is a single state tree?
The English name is Single Source of Truth, and it can also be translated into a single data source.
But what is it? Let's look at an example in life.
OK, I use a life example to make a simple analogy.
We know that in China we have a lot of information that needs to be recorded, such as personal files at school, social security records after work, provident fund records, marriage information after marriage, and other related household registration, medical care, diplomas, real estate records, etc. (There is still a lot of information).
This information is scattered in many places for management. One day when you need to do a certain business (such as entering a certain city), you will find that you need to go to each corresponding work place to print and stamp various information, and finally Submit to a place to prove that your information is correct.
This kind of information preservation scheme is not only inefficient, but also inconvenient for management, and future maintenance is also a huge task (it requires a lot of manpower from various departments to maintain, of course, the country is currently improving our system).
This is similar to our application development:
if your state information is stored in multiple Store objects, then subsequent management and maintenance will become particularly difficult.
So Vuex also uses a single state tree to manage all the states of the application level.
A single state tree allows us to find the fragments of a certain state in the most direct way, and it can also be very convenient to manage and maintain in the subsequent maintenance and debugging process.
5.2 Basic use of Getters
Sometimes, we need to get some state mutations from the store, such as the following Store:
Get the number of students whose age is greater than 20.
If we already have a getters to get a list of all students who are older than 20 years old, then the code can be written like this:
We can define getters in the Store:
getters cannot pass parameters by default. If you want to pass parameters, you can only let the getters themselves return another function.
5.3 Mutation status update
The only way to update Vuex's store status: Submit Mutation
Mutation mainly includes two parts:
- The event type of the string (type)
- A callback function (handler), the first parameter of the callback function is state.
The definition of mutation:
Update via mutation:
5.4 Mutation passing parameters
When updating data through mutation, it is possible that we wish to carry some additional parameters
- The parameter is called the payload of the mutation (Payload)
Code in Mutation:
But what if the parameter is not one?
- For example, we have a lot of parameters to pass.
- At this time, we usually pass it in the form of an object, that is, the payload is an object.
- At this time, relevant information can be retrieved from the object.
5.5 Mutation submission style
The above submission through commit is a common way.
Vue also provides another style. It is an object containing a type attribute
. The processing method in Mutation is to use the entire commit object as the payload, so the code has not changed, still as follows:
5.6 Mutation response rules
The state in the Vuex store is responsive. When the data in the state changes, the Vue component will be automatically updated.
This requires us to comply with some Vuex corresponding rules:
- Initialize the required attributes in the store in advance.
- When adding new properties to the objects in the state, use the following methods:
Method 1: Use Vue.set(obj,'newProp', 123)
Method 2: Re-assign the old object to the old object with care
5.7 Mutation constant type-concept
Let us consider the following questions:
- In the mutation, we define many event types (that is, the method names).
- When our project grows, Vuex manages more and more states, and more and more situations need to be updated, which means that there are more and more methods in Mutation.
- There are too many methods, and users need to spend a lot of experience to remember these methods, or even switch back and forth between multiple files, check the method name, and even if it is not copying, there may be mistakes.
How to avoid the above problems?
- In various Flux implementations, a very common solution is to use constants instead of Mutation event types.
- We can put these constants in a separate file to facilitate management and make all the event types of the entire app clear at a glance.
How to do it specifically?
-
We can create a file: mutation-types.js, and define our constants in it.
-
When defining constants, we can use the style in ES2015 and use a constant as the name of the function.
5.8 Mutation synchronization function
Normally, Vuex requires that the method in
our mutation must be a synchronous method. The main reason is that when we use devtools, devtools can help us capture the snapshot of the mutation.
But if it is an asynchronous operation, then devtools will not be able to track well When will this operation be completed. For
example, in our previous code, when the update is performed, the following information will be
displayed in devtools: Figure 1 However, if the code in Vuex, we use asynchronous functions: Figure 2
You will find that the info data in the state has not been changed because it cannot be traced.
So, normally, do not perform asynchronous operations in the mutation
5.9 Basic definition of Action
We emphasize that we should not perform asynchronous operations in Mutation. But in some cases, we do want to perform some asynchronous operations in Vuex, such as network requests, which
must be asynchronous. How to deal with this time?
Action is similar to mutation, but it is used to perform asynchronous operations instead of mutation.
The basic usage code of Action is as follows:
What is context?
- The context is an object with the same methods and properties as the store object.
- In other words, we can perform commit-related operations through context, and we can also obtain context.state, etc.
- But note that they are not the same object here, why? When we learn about Modules later, let's talk about it more specifically.
Is this kind of code unnecessary?
We define actions, and then commit in actions. Isn't this not pants and fart?
In fact , this is not the case. If there are asynchronous operations in Vuex, then we can do it in actions Up.
5.10 Action distribution
In the Vue component, if we call the method in the action, then we need to use dispatch: the
same, it also supports the delivery of payload:
5.11 Promise returned by Action
As we said when learning ES6 syntax earlier, Promises are often used for asynchronous operations.
In Action, we can put asynchronous operations in a Promise, and after success or failure, call the corresponding resolve or reject.
OK, let's Look at the following code:
5.12 Understanding Module
Module means module, why do we use modules in Vuex?
- Vue uses a single state tree, which means that many states will be managed by Vuex.
- When the application becomes very complex, the store object may become quite bloated.
- In order to solve this problem, Vuex allows us to divide the store into modules, and each module has its own state, mutations, actions, getters, etc.
In what way do
we organize the modules? Let’s look at the code below: In
the code above, we already have an overall organizational structure. Let’s take a look at how to write the code in specific partial modules.
We are in moduleA Add state, mutations, getters,
mutations and getters receive the first parameter is the local state object
5.13 How to write Actions in Module
How to write actions? Receive a context parameter object. The
local state is exposed through context.state, and the root node state is context.rootState.
If the global state is also needed in the getters, more parameters can be accepted
6. Project structure
When our Vuex helps us manage too much content, a good project structure can make our code clearer.