Xiaobian often uses Vuex in the project. In fact, xiaobian himself only knows what Vuex is for to solve the pain point, but he is a little confused about the specific thing. Yesterday, xiaobian made up his mind and read Vuex’s official website (vuex.vuejs.org/zh/) carefully. The harvest is still a lot, specially to share with you, but also hope that in your future interview, increase some chips and confidence. You can also follow my wechat public number, Snail Quanzhan.

Vuex is a state management mode developed specifically for vue.js applications. It uses centralized storage to manage the state of all components of an application and rules to ensure that the state changes in a predictable way. Vuex is also integrated into Vue’s official debugging tool devTools Extension (Opens New Window), providing advanced debugging functions such as zero-configuration time-travel debugging and state snapshot import and export.

This is the description of Vuex on the official website. In previous projects, Vuex was often used to store user information, such as the id of the current user, the department of the user, and the profile picture, etc. These information are obtained through the data interface. In fact, it is ok to store cookies and LocalStorage in the user’s browser. When the user exits, the corresponding information can be cleared, which also reduces multiple requests and solves the pain point of multiple components sharing data. However, Vuex is used by many admin users, and Redux is also used by React, another front-end framework. With the rapid development of the front-end, learning to use Vuex becomes even more important.

Vuex is mainly divided into four parts, State, Getters, Mutations, and Actions. Xiaobian will explain one by one in combination with examples below. Before entering the world of Vuex, we need to install Vuex

npm install vuex --save
Copy the code

When we use scaffolding to build the project, we need to explicitly introduce Vuex in the project entry file main.js and install it via vue.use ()

import Vue from 'vue'import Vuex from 'vuex'
Vue.use(Vuex)
Copy the code

Vuex relies on Promises. If you’re not familiar with Promises, check out the previous article, Promise in ES6.

A, the State

The core of Vuex is a store, and the data in the store are stored in State. State can be understood as a large warehouse, which stores the data we need to share. In this.$store, you can retrieve data from State. In order to ensure consistency, you are not allowed to modify the State directly.

So let’s create the simplest store we can

import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
const store = new Vuex.Store({  
    state: {    
        count: 0  
    },  
    mutations: {    
        increment (state) {      
            state.count++    
        }  
}})
Copy the code

Now you can retrieve state objects via store.state and trigger state changes via the store.mit method:

store.commit('increment')console.log(store.state.count) / / - > 1
Copy the code

Finally, we need to inject store into the created Vue instance like this

new Vue({  el: '#app',  store // This position can be abbreviated using es6 syntax because the key and value of the object are the same})
Copy the code

So how do we present state in Vue components? Because Vuex’s state store is responsive, the easiest way to read state from a Store instance is to return some state in computed properties (computed) :

// Create a Counter component
const Counter = {  
    template: `<div>{{ count }}</div>`.computed: {    
        count () {      
            return store.state.count    
        }  
}}
Copy the code

We could do this

const Counter = {  
    template: `<div>{{ count }}</div>`.computed: {    
        count () {      
            return this.$store.state.count    
        }  
}}
Copy the code

In fact, we can read the values in the store as normal, and we have an easier way to do it: mapState

// In the separately built version, the auxiliary function is vuex.mapstate
import { mapState } from 'vuex'
export default {  
    // ...  
    computed: mapState({    
    // Arrow functions make code more concise
    count: state= > state.count,
    // Pass the string argument 'count' equal to 'state => state.count'
    countAlias: 'count'.// In order to be able to use 'this' to get local state, you must use regular functions
    countPlusLocalState (state) {      
        return state.count + this.localCount    
    }  
})}
Copy the code

Similarly, extensions like ES6 objects can be abbreviated if the key and value values are the same, and mapState provides a similar way to use them

computed: mapState([  
    // Map this.count to store.state.count
    'count'])
Copy the code

With the advent of extended operators in ES6, we can write it more easily, which is the most common way to write small on Github

computed: {  
    localComputed () { / *... * / },  
    // Use the object expansion operator to blend this object into an external object. mapState({/ /... })}
Copy the code

Second, the Getters

For example, if we want to get the length of an array in a store, we need to do this in computed properties without Getters

computed: {  
    doneTodosCount () {    
        return this.$store.state.todos.filter(todo= > todo.done).length  
    }
}
Copy the code

This example is relatively simple, but in more complex cases, after retrieving the State data, there is a lot of processing to do. Think of a big chunk of JS code, but fortunately, Vuex provides Getters. We could write it like this

const store = new Vuex.Store({  
    state: {    
        todos: [{id: 1.text: '... '.done: true },      
            { id: 2.text: '... '.done: false}},getters: { // Expose doneTodos via Getters
        doneTodos: state= > {      
            return state.todos.filter(todo= > todo.done)    
        }  
}})
Copy the code

So when you get it, you get the content, like this

store.getters.doneTodos // -> [{ id: 1, text: '...', done: true }]
Copy the code

Getters can also accept other getters as second arguments:

getters: {  
// ...  
    doneTodosCount: (state, getters) = > {    
        return getters.doneTodos.length  
}}
Copy the code
store.getters.doneTodosCount / / - > 1
Copy the code

We can easily use it in any component:

computed: {  
    doneTodosCount () {    
        return this.$store.getters.doneTodosCount  
}}
Copy the code

Also, we can have Getters return a function in conjunction with the ES6 arrow function that actually uses the parameters passed through the page to get different results, much like the native JS filter

getters: {  
    // ...  
    getTodoById: (state) = > (id) = > {    
        return state.todos.find(todo= > todo.id === id)  
}}
Copy the code
store.getters.getTodoById(2) // -> { id: 2, text: '... ', done: false }
Copy the code

Similar to mapState above, Getters provides a similar approach

import { mapGetters } from 'vuex'
export default {  
    // ...  
    computed: {  
    // Mix getters into a computed object using the object expansion operator. mapGetters(['doneTodosCount'.'anotherGetter'.// ...    ])}}Copy the code

If you want to give a getter property another name, use object form:

. mapGetters({/ / the ` enclosing doneCount ` mapping for ` enclosing $store. Getters. DoneTodosCount `
    doneCount: 'doneTodosCount'
})
Copy the code

Reference: vuex.vuejs.org/zh/