Vuex Action vs Mutations

前端 未结 13 1084
囚心锁ツ
囚心锁ツ 2020-12-02 04:37

In Vuex, what is the logic of having both \"actions\" and \"mutations?\"

I understand the logic of components not being able to modify state (which seems smart), but

相关标签:
13条回答
  • 2020-12-02 05:33

    This confused me too so I made a simple demo.

    component.vue

    <template>
        <div id="app">
            <h6>Logging with Action vs Mutation</h6>
            <p>{{count}}</p>
            <p>
                <button @click="mutateCountWithAsyncDelay()">Mutate Count directly with delay</button>
            </p>
            <p>
                <button @click="updateCountViaAsyncAction()">Update Count via action, but with delay</button>
            </p>
            <p>Note that when the mutation handles the asynchronous action, the "log" in console is broken.</p>
            <p>When mutations are separated to only update data while the action handles the asynchronous business
                logic, the log works the log works</p>
        </div>
    </template>
    
    <script>
    
            export default {
                    name: 'app',
    
                    methods: {
    
                            //WRONG
                            mutateCountWithAsyncDelay(){
                                    this.$store.commit('mutateCountWithAsyncDelay');
                            },
    
                            //RIGHT
                            updateCountViaAsyncAction(){
                                    this.$store.dispatch('updateCountAsync')
                            }
                    },
    
                    computed: {
                            count: function(){
                                    return this.$store.state.count;
                            },
                    }
    
            }
    </script>
    

    store.js

    import 'es6-promise/auto'
    import Vuex from 'vuex'
    import Vue from 'vue';
    
    Vue.use(Vuex);
    
    const myStore = new Vuex.Store({
        state: {
            count: 0,
        },
        mutations: {
    
            //The WRONG way
            mutateCountWithAsyncDelay (state) {
                var log1;
                var log2;
    
                //Capture Before Value
                log1 = state.count;
    
                //Simulate delay from a fetch or something
                setTimeout(() => {
                    state.count++
                }, 1000);
    
                //Capture After Value
                log2 = state.count;
    
                //Async in mutation screws up the log
                console.log(`Starting Count: ${log1}`); //NRHG
                console.log(`Ending Count: ${log2}`); //NRHG
            },
    
            //The RIGHT way
            mutateCount (state) {
                var log1;
                var log2;
    
                //Capture Before Value
                log1 = state.count;
    
                //Mutation does nothing but update data
                state.count++;
    
                //Capture After Value
                log2 = state.count;
    
                //Changes logged correctly
                console.log(`Starting Count: ${log1}`); //NRHG
                console.log(`Ending Count: ${log2}`); //NRHG
            }
        },
    
        actions: {
    
            //This action performs its async work then commits the RIGHT mutation
            updateCountAsync(context){
                setTimeout(() => {
                    context.commit('mutateCount');
                }, 1000);
            }
        },
    });
    
    export default myStore;
    

    After researching this, the conclusion I came to is that mutations are a convention focused only on changing data to better separate concerns and improve logging before and after the updated data. Whereas actions are a layer of abstraction that handles the higher level logic and then calls the mutations appropriately

    0 讨论(0)
提交回复
热议问题