First, VueX
1.1 aboutVueX
VueX is a state management tool suitable for use in Vue project development. Imagine a project that frequently uses component arguments to synchronize values in data. Managing and maintaining those values can be tricky once the project becomes large. To this end, Vue provides a unified management tool — VueX — for these values that are frequently used by multiple components. In a Vue project with VueX, we just need to define these values in the VueX to be used in the components of the entire Vue project.
1.2 installation
Since VueX was developed after learning VueCli, please refer to the directory constructed by VueCli 2.x for the items that appear below.
The following steps assume that you have completed building the Vue project and have gone to the project’s files directory.
-
Npm install Vuex
npm i vuex -s Copy the code
-
Create index.js in a new store folder under the root of your project
Your project’s SRC folder should look like this
│ App. Vue │ main. Js │ ├ ─ assets │ logo. The PNG │ ├ ─ components │ HelloWorld. Vue │ ├ ─ the router │ index. The js │ └ ─ store index, jsCopy the code
1.3 the use of
1.3.1 initializationstore
Under theindex.js
The contents of the
import { createStore } from 'vuex'; Columns: testData, posts: testPosts, user: VueX export default createStore({state:{state:{column: testData, posts: testPosts, user: 'xiaomu' } })Copy the code
1.3.2 Mount Store into the Vue instance of the current project
Open the main js
import { createApp } from 'vue';
import App from './App.vue';
import router from './router';
import store from './store';
createApp(App).use(store).use(router).mount('#app');
Copy the code
1.3.3 Using Vuex in components
For example, in app.vue, we take the name defined in state and display it in the H1 tag
<template>
<global-header :user="currentUser"></global-header>
</template>
<script>
import { useStore } from 'vuex';
export default defineComponent({
setup() {
const store = useStore();
const currentUser = computed(() => {
store.state.user;
});
return {
currentUser: currentUser
};
}
})
</script>
Copy the code
1.4 Installing the Vue development tool VueDevtools
In Vue project development, it is necessary to monitor various values in the project. To improve efficiency, Vue provides a browser extension — VueDevtools.
This is even more important when learning about VueX. Use of the plugin can be found on the official website, which is not covered here.
Ii. Core content in VueX
In a VueX object, there is not only state, but also the set of methods used to manipulate the data in state, and the set of methods we need to manipulate the data in State and so on.
Membership List:
- State Storage status
- Mutations State member operation
- Getters processes state members to the outside world
- Actions Asynchronous operations
- Modules Modularization status management
2.1 VueX workflow
Flow chart from Vuex website
First of all, the Vue component needs to dispatch the Actions method in VueX to ensure data synchronization when a request from the back end or asynchronous operation occurs in the process of calling a VueX method. Action, so to speak, exists to enable the methods in mutations to work in asynchronous operations.
If there is no asynchronous operation, we can directly implement the operation on the state member by writing our own methods in Mutations in the state submission in the component. Note that as mentioned in Section 1.3.3, it is not recommended to operate directly on members of state in components, because direct modifications (e.g. Store.state. name = ‘hello’) cannot be monitored by VueDevtools.
The last modified state member is rendered to the original location of the component.
2.2 Mutations
Mutations are a collection of methods for manipulating state data, such as modifying, adding, deleting, and so on.
2.2.1 Mutations method of use
Mutations methods all have a default parameter:
( [state] [,payload] )
state
Is the currentVueX
The object of thestate
payload
Is used by the method to pass arguments when called
For example, let’s write a method that, when executed, changes the value of name in the following example to “jack”, we just need to do that
index.js
import { createStore } from 'vuex'; export default createStore({ state:{ columns: testData, posts: testPosts, user: 'xiaomu'}, mutations:{//es6 syntax, equivalent to edit:funcion(){... } edit(state){ state.user = 'jack' } } })Copy the code
In a component, we need to call the mutation like this — for example, in a method of app.vue:
store.commit('edit')
Copy the code
2.2.2 Mutation spread value
In the actual production process, you will encounter the need to carry some parameters to the method when submitting a mutation.
When a single value is submitted:
store.commit('edit',15)
Copy the code
When multiple parameter submissions are required, it is recommended that they be submitted in one object:
Store.com MIT (' edit '{age: 15, sex:' male '})Copy the code
Parameters for receiving mounts:
Edit (state,payload){state.name = 'xiaomu' console.log(payload) // 15 or {age:15,sex:' male '}}Copy the code
Another way to submit
Store.com MIT ({type:'edit', payload:{age:15, sex:' male '}})Copy the code
2.2.3 Adding and Deleting Members in the State
In order to coordinate with the responsive data of Vue, we shall use the method provided by Vue in the method of Mutations for operation. If you delete or add data using delete or xx.xx = xx, the Vue cannot respond to data in real time.
-
Vue. Set Sets the value of a member for an object, or adds it if it does not exist
For example, add an age member to the state object
Vue.set(state,"age",15) Copy the code
-
Vue.delete Deletes a member
Delete the age member you just added
Vue.delete(state,'age') Copy the code
2.3 Getters
Members in state can be processed and passed to the outside world
Methods in Getters take two default arguments
- State State object in the current VueX object
- Getters The current getters object used to take other getters under getters
For example,
Getters :{nameInfo(state){return "name :"+state.name}, FullInfo (state,getters){return getters. NameInfo +' age :'+state.age}}Copy the code
Component invocation
store.getters.fullInfo
Copy the code
2.4 the Actions
Because you operate asynchronously directly in the mutation method, you will cause data invalidation. So Actions are provided specifically for asynchronous operations, and the mutation method is eventually submitted.
Methods in Actions have two default arguments
context
Context (equivalent to this in the arrow function) objectpayload
Mount parameters
For example, we execute the edit method in Section 2.2.2 after two seconds
Since setTimeout is an asynchronous operation, you need to use Actions
actions:{
aEdit(context,payload){
setTimeout(()=>{
context.commit('edit',payload)
},2000)
}
}
Copy the code
Call from a component:
store.dispatch('aEdit',{age:15})
Copy the code
Improvement:
Since the operation is asynchronous, we can encapsulate our asynchronous operation as a Promise object
aEdit(context,payload){ return new Promise((resolve,reject)=>{ setTimeout(()=>{ context.commit('edit',payload) resolve() })}}, 2000)Copy the code
2.5 modules
When a project is large and has many states, modular management can be adopted. Vuex allows us to split the Store into modules. Each module has its own state, mutation, action, getter, and even nested submodules — split the same way from top to bottom.
modules:{ a:{ state:{}, getters:{}, .... }}Copy the code
The state of calling module A within the component:
store.state.a
Copy the code
Commit or dispatch a method, as before, automatically executes methods of the corresponding type in all modules:
store.commit('editKey')
store.dispatch('aEditKey')
Copy the code
2.5.1 Module details
-
The first parameter accepted by the methods mutations and getters in the module is the state inside its own local module
modules:{ a:{ state:{key:5}, mutations:{ editKey(state){ state.key = 9 } }, .... }}Copy the code
-
The third argument to the method in getters is the root node state
modules:{ a:{ state:{key:5}, getters:{ getKeyCount(state,getter,rootState){ return rootState.key + state.key } }, .... }}Copy the code
-
The actions method gets the local module state as context.state and the root node state as context.rootState
modules:{ a:{ state:{key:5}, actions:{ aEidtKey(context){ if(context.state.key === context.rootState.key){ context.commit('editKey') } } }, .... }}Copy the code
Third, standardize the directory structure
It doesn’t make sense to put the entire store in index.js, so it needs to be split. A suitable directory format is as follows:
Store :. │ actions. Js │ index. Js │ mutations. Js │ mutations_type. │ ├ ─modules astore.js as neededCopy the code
The corresponding content is stored in the corresponding file, as before, in index.js and exported to Store. Try to put the data in index.js. The Astore local module states in modules can also be subdivided if there are many.