Vuex data management

How to understand data management?

This Vuex vue the data management center, believe seen strong-arm reaction is known to all, independent regiment originally independent regiment that li management is to want to drink and eat meat meat, want to fight the war, but the independent regiment is chaotic, and it is as same as our vue If the data in the data inside as you take in, it also is very chaotic, So we need a separate data center. Zhao Gang, the political commissar, was in charge of the regiment’s daily life. The commissar was in charge of daily life and the regiment commander was in charge of fighting. Thus, the division of labor was relatively clear. Vuex is our commissar. Come to our data management, any management can not be directly operated, but unified deployment and forwarding through Vuex.

Managing changing states is difficult. If a change in one model causes a change in another model, then a change in the View may cause a change in the corresponding model as well as in the other model, which in turn may cause a change in the other view. Until you can’t figure out what’s going on. When, for what reason, and how state changes are out of control. When systems become complex, it can be difficult to reproduce problems or add new features. — From Redux Chinese Document

  1. Start the installation

    npm install vuex --save  
    Copy the code
  2. The core concept

    • Store: Our data management center, any operation needs to go through store, that is, our Political commissar Zhao
    • State: Is where we store our data
    • Mutations: We all need to modify the data through mutations
  3. use

    • The new store. Js

      import Vuex from 'vuex';
      import Vue from 'vue';
      Vue.use(Vuex);  // We cannot use it in main.js, although it is similar to our router
      export default new Vuex.Store({
          state: {count:0}})Copy the code
    • To mount our store.js to our prototype chain

      import Vue from 'vue'
      import App from './App.vue'
      import VueRouter from 'vue-router';
      import router from './routes';
      import store from './store';
      Vue.config.productionTip = false;
      Vue.use(VueRouter); // Mount this.$router to the prototype chain so that vue can handle routing
      
      new Vue({
          router,
          store, // It is equivalent to mounting our store on the prototype chain
          render: h= > h(App),
      }).$mount('#app');
      Copy the code
    • Data usage is retrieved in. Vue using this.$store

      <script>
          export default {
              name: "Page2".computed: {count(){
                      return this.$store.state.count
                  }
              }
          }
      </script>
      Copy the code
  4. When we make changes to state’s data, you want to do this directly

    If you think about it, isn’t it back to where we used to change state for other components, and then you end up having trouble finding the source of the problem or adding new features?

    <script>
        export default {
            name: "Page2".created(){
                setTimeout(() = >{
                    this.$store.state.count++
                },2000)
            },
        }
    </script>
    Copy the code

    — Solve the strict mode of using VUEX, modify data using mutations

    / / -- -- -- -- -- -- -- -- -- -- -- -- -- - store. Js
    export default new Vuex.Store({
        state: {count:0
        },
        strict:true  // Use strict mode
    })
    
    Copy the code
  5. Use mutations to modify the data

    In VUEX, the way to change state is to commit mutation. The official document reads:

    The only way to change the state in Vuex’s store is to commit mutation.

    export default new Vuex.Store({ state:{ count:0 }, mutations:{ increment(state){ state.count++ } }, // Use strict mode})Copy the code
    // We can't get supplies directly now, we have to go to commissar level to get supplies at once
    created(){
         setTimeout(() = >{
             // this.$store.state.count++
             this.$store.commit('increment')},2000)},Copy the code
  6. There are actually two ways to change state

    • You can see the description of strict mode in the official Vuex documentation

      To turn on strict mode, simply pass strict: true when creating a store; In strict mode, an error is thrown whenever a state change occurs that is not caused by a mutation function. This ensures that all state changes are tracked by the debugging tool.

    • So vuEX is set to strict mode.

      Modifying state directly found that the console had indeed reported an error, but state was successfully modified and remained responsive. Error message:

      Do not mutate vuex store state outside mutation handlers.

      • When state is modified by committing mutation, vUE’s debugging tool can record every state change for easy debugging. However, if you modify state directly, there is no record of this.
    • Analysis of the source code

      • Mutation modifies the state via commit, which you can see is handled by the this._withcommit function

      • Look at _ withCommit, _ withCommit takes fn which is the function we used to change the state, so before we execute fn, we call this.comiting =true, and when fn is done, Then this. _commiting = commiting

      • So what does commiting have to do with strict:true setting for strict mode

      • What does enableStrictMode() do?

        Inside the enableStrictMode function, the $watch function is called to observe the state change. When state changes, assert is called to determine the value of store. _commiting(this.committing above), and if it is not true, an exception is raised:

      • So if you change state externally, you don’t commit (commit), you don’t execute withCommit (this. _ withresearch ()), so when enableStrictMode is executed, Assert is called because _withresearch doesn’t true (right), you get an exception.

  7. Getters: Vuex also needs computations internally for this functionality, such as formatting data

    Sometimes we need to derive some state from state in the Store, which can be interpreted as computed functionality for data in VUEX

    //--------------store.js
    getters: {money:state= > `${state.count*1000}`
    },
    
    Copy the code
    / / -- -- -- -- -- -- -- -- -- -- -- -- -- -. The vue file
    computed: {money(){
            return this.$store.getters.money
        }
    }
    
    Copy the code
  8. Action: Modifies data

    However, Mutations must be synchronous, and Action is an asynchronous Mutation, which is used together with Dispatch. It is an asynchronous task by definition. Dispatch is used asynchronously for most tasks including network request, network data acquisition and file reading

    / / -- -- -- -- -- -- -- -- -- -- -- -- -- -. The vue file
     created(){
     // setTimeout(()=>{
     // // this.$store.state.count++
     / /}, 2000)
         this.$store.dispatch('incrementAsync')  // Inside incrementAsync we perform our asynchronous operations again
         this.$store.dispatch('incrementAsync', {// You can also add parameters
             num:10})},Copy the code
    //--------------store.js
    mutations: {increment(state,args){
            state.count+= args.num || 1  // Change the parameter}},actions: {incrementAsync(store,args){
            setTimeout(() = >{
                store.commit('increment',args);// Go to perform the task of Mutations, args parameters
            },2000)}},Copy the code
  9. mapState

    When a component needs to fetch more than one state, declaring those states as computed properties makes code redundant and repetitive

    To solve this problem, use the mapState helper function to help us generate computed properties

    computed:{
        count(){
            return this.$store.state.count
        },
        ...  // And a bunch of attributes
    }
    
    Copy the code
    computed:{ ... mapState({count:state= >state.count
        })
        // count(){
        // return this.$store.state.count
        // }
    }
    
    Copy the code
  10. mapActions

    Just like mapState, map the Actions method in

    created(){
        // this.$store. Dispatch ('incrementAsync',
        // num:10
        // });
        this.incrementAsync({  // Use the more elegant, more component-like code directly
            num:10})},methods: {... mapActions(["incrementAsync"])},Copy the code
  11. mapMutations

    Smart as you must have thought of mapMutations as I did

    setTimeout(() = >{
        this.increment({num:1})},2000)
    
     methods: {... mapMutations(["increment"])},Copy the code
  12. To summarize

    State: Used to save the status. After registering store in the root instance, access it with this.$store.state.

    Getters: states derived from state. You can think of it as a state-based calculated property. Most of the time, you don’t need Getters and just use State.

    Mutations are used to change the status. It is important to note that the changes in the status of Mutations must be simultaneous. After registering store in the root instance, use this. codestore.mit (‘ XXX ‘, data) to notify Mutations to change the status.

    Actions: Change the status by calling Mutations. Actions can contain asynchronous Actions. When a store is registered in the root instance, you can use this.$store.dispatch(‘ XXX ‘, data) to store trigger actions.

  13. Vuex complete data flow