Vuex (3) getters, actions


Actions内部からstateにアクセスしないでください.演算も操作stateも変異で行わなければならない.

1. getters


同じコード、同じ論理を持つ素子が繰り返される場合に使用されますか?getters
  • TheCounter.vueはstate incounterを出力する素子です.これにほぼ似た構成部品FavoriteCounter.Vueが作成された場合...→繰り返しが多ければ多いほど、項目が大きくなるほど煩雑になる.
  • FavoriteValue.vue
    <template>
        <h3>{{counter}}</h3>
        <p>We do more...</p>
    </template>
    
    <script>
    export default {
        computed:{
            counter(){
                return this.$store.state.counter * 2;
            }
        }
    }
    </script>
    
    <style>
    
    </style>
    そのため、main.jsにgettersを使用します.
    main.js
    getters: {
            finalCounter(state) {
                return state.counter * 3;
            },
        }
  • すべてのgetterには方法があります
  • TheCounter.vue & FavoriteValue.vue
    <template>
        <h3>{{counter}}</h3>
    </template>
    
    <script>
    export default {
        computed:{
            counter(){
                return this.$store.getters.finalCounter;
            }
        }
    }
    </script>
    
    <style>
    
    </style>
    FavoriteValue.vueでは、カウンタ値が100を超えると100、0未満で0と表示されます.
    main.js
    getters: {
            finalCounter(state) {
                return state.counter * 3;
            },
            normalizedCounter(state, getters) {
                const finalCounter = getters.finalCounter;
                if (finalCounter < 0) {
                    return 0;
                } if (finalCounter > 100) {
                    return 100;
                }
                return finalCounter;
            }
  • NormalizedCounterに示すように、getterは1行以上のコードを持ち、値を返さなければならない.
  • (コツ)ここには2つのパラメータがありますがstateは使用されていませんので、vueは警告文を与える可能性があります.こんな時は何も言わない.
  • 2番目のパラメータgettersで別のgetterを呼び出すこともできます.ここでcontで宣言したfinalCounterはgetterで宣言したfinalCounter()メソッドと同様の演算を行うため,パラメータとしてより効率的で説得力がある.
    結果は以下の通りです.
  • main.js完全コード
  •     import { createApp } from 'vue';
        import { createStore } from 'vuex';
        
        import App from './App.vue';
        
        const store = createStore({
            state() {
                return {
                    counter: 0
                };
            },
            mutations: {
                increment(state) {
                    state.counter += 2;
                },
                increase(state, payload) {
                    state.counter = state.counter + payload.value;
                }
            },
            getters: {
                finalCounter(state) {
                    return state.counter * 3;
                },
                normalizedCounter(_, getters) { //안쓰는 인자는 _ 하면 에러메시지 안뜬대 -> 211005수정) 에러 뜨는데?
                    const finalCounter = getters.finalCounter;
                    if (finalCounter < 0) {
                        return 0;
                    } if (finalCounter > 100) {
                        return 100;
                    }
                    return finalCounter;
                }
            }
        });
        
        const app = createApp(App);
        
        app.use(store);
        
        app.mount('#app');

    2. actions

  • 突然変異は同期する必要があります.つまり、非モチベーションは使わないほうがいいということです.
  • 理由.→複数の変異を実行すると、すべての変異が最新の状態になります.別の変異をコミットしたときにまだ完了していない場合、state値にエラーが発生する可能性があります.
    (mutationでsettimeoutを使用できますが、後で問題が発生する可能性があるので使用しないでください)
    🗣️ : では、非同期を実行する場合はどうすればいいのでしょうか.
    Actionsを使用すると非同期になります!
  • gettersと突然変異の間で使用できます.
  • actionsはobjectメソッドを有し、メソッド名は他の場所で実装される関数名と同じであってもよい.→これは逆に複雑なコードの間で分かりやすい.
  • main.js
    actions: {
            increment(context) {
                setTimeout(function () {
                    context.commit('increment')
                }, 2000);
            },
            increase(context, payload) {
                context.commit('increase', payload);
            }
        },
  • actionsの方法は論点としてコンテキストを有する.contextは他のすべての機能と同様に、Vuexによって自動的に取得されます.
  • 突然変異で実現できる方法をcommitと呼ぶことができる.
  • increate()と同様にcontext、payloadの2つのパラメータを受け入れることができます.
  • App.vue
    methods: {
        addOne() {
          this.$store.commit('increase', { value: 10 }); //commit 표현법1
    
          this.$store.dispatch({ 
            type:'increment',
          });
        },
      },
  • actionsは、次のdispatchで使用できます.
  • 結果)Add 2ボタンを押すと、2秒後にカウンタが2増加します.
  • main.js完全コード
        import { createApp } from 'vue';
        import { createStore } from 'vuex';
        
        import App from './App.vue';
        
        const store = createStore({
            state() {
                return {
                    counter: 0
                };
            },
            mutations: {
                increment(state) {
                    state.counter += 2;
                },
                increase(state, payload) {
                    state.counter = state.counter + payload.value;
                }
            },
            actions: {
                increment(context) {
                    setTimeout(function () {
                        context.commit('increment')
                    }, 2000);
                },
                increase(context, payload) {
                    context.commit('increase', payload);
                }
            },
            getters: {
                finalCounter(state) {
                    return state.counter * 3;
                },
                normalizedCounter(getters) {
                    const finalCounter = getters.finalCounter;
                    if (finalCounter < 0) {
                        return 0;
                    } if (finalCounter > 100) {
                        return 100;
                    }
                    return finalCounter;
                }
            }
        });
        
        const app = createApp(App);
        
        app.use(store);
        
        app.mount('#app');