Vuex rebuilt by vue [Part 1]

Article directory

  • Copyright Notice
  • Vuex overview
    • Main concepts and components of Vuex
  • Use of vuex
  • state
    • Vuex features
  • Access data in vuex
    • $store access
    • mapState helper function access
  • Turn on strict mode and Vuex’s single data flow
  • mutations
    • First introduction to mutations
    • mutations with parameters
    • Helper function mapMutations
  • Actions
    • Helper function mapActions
  • vuex mutations VS actions
  • Getters
  • Summarize

Copyright Statement

  • The content of this blog is based on my personal study notes from the Dark Horse Programmer course. I hereby declare that all copyrights belong to Dark Horse Programmers or related rights holders. The purpose of this blog is only for personal learning and communication, not commercial use.
  • I try my best to ensure accuracy when organizing my study notes, but I cannot guarantee the completeness and timeliness of the content. The content of this blog may become outdated over time or require updating.
  • If you are a Dark Horse programmer or a related rights holder, if there is any copyright infringement, please contact me in time and I will delete it immediately or make necessary modifications.
  • For other readers, please abide by relevant laws, regulations and ethical principles when reading the content of this blog, refer to it with caution, and bear the resulting risks and responsibilities at your own risk. Some of the views and opinions in this blog are my own and do not represent the position of Dark Horse Programmers.

Vuex Overview

  • uex is a state management library for Vue.js [state is data]. In short, Vuex is a plug-in that can help us manage Vue’s common data (data shared by multiple components).
  • scenes to be used
  • Advantage
    • Jointly maintain a data, centralized data management
    • Responsive changes
    • Simple operation

The main concepts and components of Vuex

  • State: State in Vuex is where application data is stored, usually represented as JavaScript objects.

  • Getters: Getters are used to calculate derived states based on the current state, similar to computed properties in repositories.

  • Mutations: Mutation is the only way to modify state. They aresynchronous and help maintain a predictable state by clearly defining how the state changes.

  • Actions: Actions are used to perform asynchronous operations and trigger mutations. Good for tasks like making API requests and then submitting mutations based on the results.

  • Modules: Vuex allows storage to be divided into modules. This helps for larger applications to organize state, mutations, actions, and getters into smaller, more manageable pieces.

  • Vuex is particularly useful for larger applications where state management can become complex.

  • It enforces one-way data flow and makes it easier to track the source of application state changes. This predictability helps debug and maintain growing applications.

Usage of vuex

  • General steps for setting up Vuex in a Vue.js application
  1. Installation: You need to install Vuex as a dependency, which can be done using npm or yarn.

    npm i vuex@3 # vue2 applicable
    
  2. Store Configuration: Create a store by defining states, mutations, actions, and getters.

    • In order to keep the project directory clean, create a new store directory under the src directory and place an index.js file under it.
     // store.js
       import Vue from 'vue'
       import Vuex from 'vuex'
    
       Vue.use(Vuex)
    
       const store = new Vuex.Store({<!-- -->
         state: {<!-- -->
           // Define the state of the application here
         },
         mutations: {<!-- -->
           // Define mutation function here
         },
         actions: {<!-- -->
           //Define action function here
         },
         getters: {<!-- -->
           // Define the getter function here
         }
       })
       export default store
    
  3. Import and mount it to the Vue instance in main.js

    import Vue from 'vue'
    import App from './App.vue'
    import store from './store'
    
    Vue.config.productionTip = false
    
    new Vue({<!-- -->
      render: h => h(App),
      store
    }).$mount('#app')
    
  4. Test printing Vuex

    created(){<!-- -->
      console.log(this.$store)
    }
    

State (state)

  • State is a collection of data in an application, typically represented as a JavaScript object containing various properties. These properties can include the application’s configuration, user information, page content, various settings, etc.
  • State provides the only public data source, and all shared data must be stored in the State in the Store.
  • The state of the application is defined in the state attribute of the store object.
const store = new Vuex.Store({<!-- -->
  // state state, that is, data, is similar to data in vue components,
  // the difference:
  // 1.data is the component’s own data,
  // 2. The data in state can be accessed by the components of the entire vue project.
  state: {<!-- -->
    user: null,
    settings: {<!-- -->
      theme: 'light',
      language: 'en',
    },
    //Other application status
  },
  //Other configuration items
})

Vuex features

  • Some important features of state in Vuex
    • Centralized: State in Vuex is centrally managed, which means that all components can access the same state data without the need to pass data through complex components to achieve sharing.

    • Reactive: Vuex’s state is reactive. When state changes, components that depend on that state automatically update to reflect those changes.

    • Read-Only: Vuex’s status is read-only. This means that you cannot modify the state directly in the component, but need to modify it through mutations. This helps maintain predictability of state.

    • Single Source of Truth: Vuex encourages centralizing the application’s state into a single state tree, making it the “single source of truth” for the entire application. This helps simplify the management and maintenance of state.

    • Predictable: Because state modifications can only be made through mutations, state changes become predictable and easy to debug and maintain.

Access data in vuex

  1. Direct access via $store -> {{ $store.state.count }}
  2. Map calculated properties through auxiliary function mapState -> {{ count }}

$store access

  • Get the store via the $store access syntax
    :
     1. Get this.$store in Vue template
     2. Get import from the js file and import the store
    
    
    In the template: {<!-- -->{<!-- --> $store.state.xxx }}
    In component logic: this.$store.state.xxx
    In JS module: store.state.xxx
    
  • used in template
    • To access the state in Vuex in a component, you can use this.$store.state to get the value of the state
<template>
  <div>
    <p>User: {<!-- -->{<!-- --> $store.state.user }}</p>
    <p>Theme: {<!-- -->{<!-- --> $store.state.settings.theme }}</p>
  </div>
</template>
  • Used in component logic
    • Define the state attribute in the calculated attribute
    <h1>state data - {<!-- -->{<!-- --> count }}</h1>
    
    // Define the data in the state in the calculated properties within the component
      computed: {<!-- -->
        count () {<!-- -->
          return this.$store.state.count
        }
      }
    
  • js file used
//main.js

import store from "@/store"

console.log(store.state.count)

mapState auxiliary function access

  • MapState is an auxiliary function that maps data in the store to the calculated properties of the component. It is a convenient usage.
  • Step 1: Import mapState (mapState is a function in vuex)
    import {<!-- --> mapState } from 'vuex'
    
  • Step 2: Use the array form to introduce the state attribute
    mapState(['count'])
    
    • The above code is equivalent to
    count () {<!-- -->
        return this.$store.state.count
    }
    
  • Step 3: Use the expansion operator to map the exported state to the computed attribute
     computed: {<!-- -->
        ...mapState(['count'])
      }
    
     <div> state data: {<!-- -->{<!-- --> count }}</div>
    

Enable strict mode and Vuex’s single data flow

  • vuex also follows one-way data flow, and the warehouse data cannot be directly modified in the component.
  1. Modify the value of state in Vuex directly in the component
  • Son1.vue
button @click="handleAdd">Value + 1</button>

methods:{<!-- -->
handleAdd (n) {<!-- -->
      // Error code (vue will not monitor by default, monitoring requires cost)
       this.$store.state.count + +
      // console.log(this.$store.state.count)
    },
}
  1. Enable strict mode
    • Strict mode can be turned on through strict: true. After turning on strict mode, directly modifying the value in state will result in an error.
    • State data can only be modified through mutations, and mutations must be synchronous

Mutations

First introduction to mutations

  1. Define mutations
const store = new Vuex.Store({<!-- -->
  state: {<!-- -->
    count: 0
  },
  // define mutations
  mutations: {<!-- -->
     
  }
})
  1. Format description
  • Mutations are an object that stores methods for modifying state.
mutations: {<!-- -->
    //The first parameter in the method is the state attribute of the current store
    // payload load transportation parameters When calling mutaions, you can pass parameters and pass the load
    addCount (state) {<!-- -->
      state.count + = 1
    }
  }
  1. Submit mutations in the component
this.$store.commit('addCount')

With parameters mutations

  • Submitting mutations allows you to pass parameters this.$store.commit('xxx', parameters)
  1. Provide mutation function (with parameters)
    mutations: {<!-- -->
      ...
      addCount (state, count) {<!-- -->
        state.count = count
      }
    }
    
  2. Submit mutation
    handle ( ) {<!-- -->
      this.$store.commit('addCount', 10)
    }
    
  3. Tips: You can only submit one parameter. If there are multiple parameters to be passed, you can pass an object
    this.$store.commit('addCount', {<!- - -->
      count: 10
    })
    

Auxiliary function mapMutations

  • mapMutations is very similar to mapState. It extracts the methods located in mutations and maps them to component methods.
    import {<!-- --> mapMutations } from 'vuex'
    methods: {<!-- -->
        ...mapMutations(['addCount'])
    }
    //Equivalent to
    methods: {<!-- -->
      // commit(method name, payload parameters)
      addCount () {<!-- -->
          this.$store.commit('addCount')
      }
    }
    
    • In the component, you can call it directly through this.addCount
    <button @click="addCount">Value + 1</button>
    
  • Please note: Vuex mutations require that asynchronous code cannot be written. If there are asynchronous ajax requests, they should be placed in actions

Actions

  • Actions are used to handle asynchronous operations, such as getting data from the server or performing complex calculations. Actions can contain any asynchronous operation, but they ultimately require mutations to be called to update data in the state.

  • Actions are called through the dispatch method, which receives an action name and an optional payload parameter. When the dispatch method is called, it triggers an action, and any asynchronous operation can be performed in the action.

  1. Define actions
mutations: {<!-- -->
  changeCount (state, newCount) {<!-- -->
    state.count = newCount
  }
}


actions: {<!-- -->
  setAsyncCount (context, num) {<!-- -->
    //After one second, give a number to modify num
    setTimeout(() => {<!-- -->
      context.commit('changeCount', num)
    }, 1000)
  }
}
  1. Called through dispatch in the component
setAsyncCount () {<!-- -->
  this.$store.dispatch('setAsyncCount', 666)
}

Auxiliary function mapActions

  • mapActions extracts the methods located in actions and maps them to component methods.
  • Son.vue
    import {<!-- --> mapActions } from 'vuex'
    methods: {<!-- -->
       ...mapActions(['changeCountAction'])
    }
    
    //The code mapped by mapActions is essentially the writing of the following code
    //methods: {<!-- -->
    // changeCountAction (n) {<!-- -->
    // this.$store.dispatch('changeCountAction', n)
    // },
    //}
    
  • You can call
    <button @click="changeCountAction(200)"> + asynchronous</button> directly through this. method
    

vuex mutations VS actions

< /table>

  • In general
    • Mutations are suitable for synchronous operations and are used to modify data in state. They are traceable and their calls can be viewed in devtools.
    • Actions are suitable for performing asynchronous operations, calling multiple mutations, or processing complex logic. They can be synchronous or asynchronous operations, and can return a Promise or the result of an asynchronous operation.
    • In terms of calls, mutations use the commit method, while actions use the dispatch method.

Getters

  • Getters are used to obtain data from the store, similar to calculated properties, and can calculate a new value based on the state in the store.
  • Getters can be regarded as computed properties of store. Their values will be cached and will only be recalculated when the dependent state changes.
  • Benefits: The data processing logic can be extracted from the component and placed in the store, making the component more concise and easier to maintain. In addition, getters can be shared and reused in multiple components to avoid code redundancy.
  • getter example:
    • Define the getter of doneTodos, which calculates a new array based on the todos array in the store, which contains all completed todo objects.
    const getters = {<!-- -->
     //getters: {<!-- -->
     // The first parameter of the getters function is state
     // There must be a return value
      doneTodos: state => {<!-- -->
        return state.todos.filter(todo => todo.done)
      }
    }
    
  • access getters
    • Use store to access getters
    {<!-- -->{<!-- --> $store.getters.doneTodos}}
    
    • To use this getter in a component, use the mapGetters helper function
import {<!-- --> mapGetters } from 'vuex'

export default {<!-- -->
  computed: {<!-- -->
    ...mapGetters([
      'doneTodos'
    ])
  }
}

Summary

  • Summary of the use of state, getters, mutations and actions in Vuex:
Mutations Actions
Purpose Modify data in state Perform asynchronous operations and call multiple mutations
Synchronous/asynchronous Synchronous operations Can be synchronous or asynchronous operations
Usage scenarios Update data in state Execute asynchronous requests and handle complex logic
Calling method Use commit method to call Use dispatch method to call
Response Cannot return any value, can only modify state Can return the result of Promise or asynchronous operation
Tracking You can track the calls of mutations in devtools You can track the calls of actions in devtools

td>

State Getters Mutations Actions
Purpose Storing application data Deriving calculated properties from state Modification Data in state Perform asynchronous operations and call multiple mutations
Access directly Use this.$store.state Use this.$store.getters No direct access, call through commit method No direct access, call through dispatch method
Usage examples this.$store.state.count this.$store.getters.doneTodos this.$store .commit(‘increment’) this.$store.dispatch(‘fetchData’)
Parameters None Receive state as parameter Receive state and payload as parameter Receive context object as parameter
Return value None Returns calculated properties or derived data based on state No return value, only state can be modified Promise or Promise can be returned Results of asynchronous operations
Asynchronous operations Not applicable Not applicable Not applicable Applicable
Tracking None The call of getters can be traced in devtools You can track the calls of mutations in devtools You can track the calls of actions in devtools