Vuex state manager

Keywords: Front-end Vue Vue.js

1 Introduction

         Vuex is a state management mode specially developed for Vue.js applications. It uses centralized storage to manage the state of all components of the application, and ensures that the state changes in a predictable way with corresponding rules.
         Application scenario: communication between components at the same level, such as the following:

	let comA = {}
    let comB = {}

2 basic use

2.1 state

        State (similar to data in vue instances) the state component stores shared data and extracts public variables from each vue instance for unified management.

	state: {       
	    msg: 'hello vuex'
	}
	//In vue, the state stored in vuex is obtained by calculating attributes, which can be obtained directly or through auxiliary functions
     computed: {
        count() {
            return this.$store.state.count
        }
            // perhaps
            ...Vuex.mapState(["count"])
      }

2.2 getters

        Getters (similar to computed in the vue instance) is a method used to calculate and return the static data in the state after obtaining the state and processing the state data.

    getter: {
        //Parameter is the default parameter -- derived from state
        reMsg(state) {
           Returns the result after the operation
           return state.msg.toUpperCase()
        }
    }
   stay vue Can be accessed by calculating properties
   computed: {
      reMsg() {
         return this.$store.getters.reMsg
      }
      // perhaps
      ...Vuex.mapGetters(["reMsg"])
    }

2.3 mutations

        Changes is the only way to modify state data. It is generally used for some synchronization operations. The only way to change the state in Vuex's store is to submit changes, which must be synchronous operations. The first parameter of the mutation function is state, and the second parameter is to accept the arguments passed by the user when calling mutation.

 mutations: {
      SET_MSG(state, payload) {
        state.msg = payload
      }
    }
  Can be in vue Submit mutation in life cycle hook or methods Mapping mutation method in
    created() {
      // The first parameter is the name of the mutation method, and the second parameter is the passed argument
      this.$store.commit('SET_MSG', 'hello mutation')
    }
    methods:{
      ...Vuex.mapMutations(['SET_MSG'])
    }

2.4 actions

        actions is used to store asynchronous request methods. actions submit mutation, which indirectly changes the state in state. Asynchronous requests in action s accept a formal parameter - context (context object)
        (1)context.state get state
        (2)context.getters get Getters
        (3)context.commit() commit
        (4)context.dispatch() distribution action

 actions: {  
    async findAll(context) {
      let res = await axios.get('http://...');
      // Submit mutation
      context.commit('SET_MSG', res.data.data)
    }
  }
  Can be in vue Distribute actions in the lifecycle hook or methods Medium mapping actions Methods in
    created() {
      // Parameter 1 is the name of the asynchronous function, and parameter 2 can pass arguments
      this.$store.dispatch('findAll')
    }
    methods:{
      ...Vuex.mapActions(['findAll'])
    }

2.5 case - define state machine instance

    <title>vue</title>
    <script src="../js/vue.js"></script>
    <script src="../js/vuex.js"></script>
</head>
<body>
    <div id="app">
        <h3>{{data1}}</h3>
        <h4>
            vuex-state-{{msg}}
            <button @click="$store.commit('SET_MSG','bye vuex')">Modify state machine button</button>
        </h4>
        <h5>vuex-getters-{{upperMsg}}</h5>
        <ul>
            <li v-for="(item,index) in categories" :key="index">
                Column No.:{{item.id}}
                Column name:{{item.name}}
            </li>
        </ul>
    </div>
    <script>
        // 1. Declare Vuex instances
        let store = new Vuex.Store({
            state:{
                msg:'this is vuex data',
                categories:[]
            },
            getters:{
                upperMsg(state){
                    return state.msg.toUpperCase()
                }
            },
            // Change of internal state of state machine
            mutations:{
                // Mutation is the only way to modify the data in state
                // The mutation method accepts two formal parameters, the first is state, and the second is the argument passed when calling the mutation
                SET_MSG(state,payload){
                    state.msg = payload;
                },
                SET_CATEGORIES(state,payload){
                    state.categories = payload;
                }
            },
            actions:{
                // Action, which is used to store asynchronous methods shared by components
                // context object
                async findAllCategories(context){
                    // es6
                    // let res = await ajax ()
                    let res = {
                        status:200,
                        message:'query was successful',
                        data:[
                            {id:1,name:'Campus news'},
                            {id:2,name:'Campus information'},
                            {id:3,name:'Entertainment News'},
                            {id:4,name:'Campus news'},
                        ],
                        timestamp:1634817659543
                    }
                    // Submit mutation to modify the data inside the state machine
                    console.log(context);
                    // Submit the mutation through the commit() method. The first parameter is the name of the mutation function, and the second is the argument of the mutation function
                    context.commit('SET_CATEGORIES',res.data)
                }
            }
        })

        let vm = new Vue({
            el:"#app",
            data:{  
                data1:'this is vm data'
            },
            computed:{
                // Map the data in vuex state by calculating attributes
                msg(){
                    return this.$store.state.msg
                },
                categories(){
                    return this.$store.state.categories;
                },
                // By calculating attributes, vuex
                upperMsg(){
                    return this.$store.getters.upperMsg
                },
            },
            methods:{},
            created(){
                // In this hook function, the action in the vuex state machine is called.
                // Distribute actions through dispatch()
                this.$store.dispatch('findAllCategories');
                // Submit mutation
                // this.$.store.commit('SET_MSG ',' Hello, state machine ')
            },
            // 2. Inject the state machine instance into the vue instance
            store:store
        })
    </script>

3 auxiliary function

        The Vuex constructor provides a quick method for mapping data and methods. It uses the object deconstruction to deconstruct the internal auxiliary functions.

let { mapState, mapGetters, mapMutations, mapActions } = Vuex
    use
      computed: {
        ...mapState(['msg']),          // State mapping 
        ...mapGetters(['reMsg'])       // Calculate attribute mapping
      },
      methods: {
        ...mapMutations(['SET_MSG']),  // Mutation mapping
        ...mapActions(['findAll'])     // Action mapping
      }

4. Modular development

4.1 purpose of modularization

        Due to the use of a single state tree, all the states of the application will be concentrated in a relatively large object. When the application becomes very complex, the store object may become quite bloated. To solve the above problems, Vuex allows us to divide the store into modules. Each module has its own state, mutation, action, getter, and even nested sub modules. Named means to set the namespace

4.2 modular use

<title>Modular development</title>
  <script src="../js/vue.js"></script>
  <script src="../js/vuex.js"></script>
</head>

<body>
  <div id="app">
    <div>moduleA: state-{{msg1}} getters-{{upperMsg1}}
      <button @click="SET_MSG1('Hello, modularity A')">modify A data</button>
    </div>
    <div>moduleB: state-{{msg2}} getters-{{upperMsg2}}
      <button @click="SET_MSG2('Hello, modularity B')">modify B data</button>
    </div>
  </div>
  <script>
    // 1. Define state machine sub module
    let moduleA = {
      namespaced: true,
      state() {
        return {
          msg1: 'this is moduleA data'
        }
      },
      getters: {
        upperMsg1(state) {
          return state.msg1.toUpperCase()
        }
      },
      mutations: {
        SET_MSG1(state, payload) {
          state.msg1 = payload
        }
      },
      actions: {}
    }
    let moduleB = {
      namespaced: true,
      state() {
        return {
          msg2: 'this is moduleB data'
        }
      },
      getters: {
        upperMsg2(state) {
          return state.msg2.toUpperCase()
        }
      },
      mutations: {
        SET_MSG2(state, payload) {
          state.msg2 = payload
        }
      },
      actions: {}
    }
    let store = new Vuex.Store({
      modules: {
        a: moduleA,
        b: moduleB
      }
    })

    let { mapState, mapGetters, mapMutations, mapActions } = Vuex

    let vm = new Vue({
      el: '#app',
      data: {},
      computed: {
        // In the calculation attribute, map the state/getters in vuex through auxiliary functions
        ...mapState('a', ['msg1']),
        ...mapState('b', ['msg2']),
        ...mapGetters('a', ['upperMsg1']),
        ...mapGetters('b', ['upperMsg2']),
      },
      methods: {
        // In the methods of the instance, map changes through auxiliary functions
        ...mapMutations('a', ['SET_MSG1']),
        ...mapMutations('b', ['SET_MSG2']),
      },
      created() {

      },
      store
    })
  </script>

Posted by kellerkind on Thu, 21 Oct 2021 07:28:49 -0700