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 initializationstoreUnder theindex.jsThe 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] )

  • stateIs the currentVueXThe object of thestate
  • payloadIs 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

  • contextContext (equivalent to this in the arrow function) object
  • payloadMount 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.