ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Vue.js - Vuex getters, mutations
    IT/Vue.js 2020. 7. 28. 15:20
    반응형

    1. Getter 란?

     

    중앙 데이터 관리식 구조에서 발생하는 문제점 중 하나는 각 컴포넌트에서 Vuex의 데이터를 접근할 때 중복된 코드를 반복호출 하게 되는 것입니다.

    예를들면 아래와 같은 코드가 있습니다.

     

     

    여러 컴포넌트에서 같은 로직을 비효율적으로 중복 사용하고 있습니다.

    이 때, Vuex의 데이터 (state) 변경을 각 컴포넌트에서 수행하는 것이 아니라,

    Vuex에서 수행하도록 하고 각 컴포넌트에서 수행 로직을 호출하면, 코드 가독성도 올라가고 성능에서도 이점이 생깁니다.

     

     

     

     

    2. Getters 등록

     

    상위 컴포넌트 : TestVueComponent.vue

    하위 컴포넌트 : ChildVuex.vue

     

    getters를 Vuex에 추가합니다.

    export default new Vuex.Store({
      // ...
     
     
      getters: {
        getCounter: function (state) {
          return state.counter
        }
      }
    })

     

     

     

    3. Getters 사용

     

    등록된 getters를 각 컴포넌트에서 사용하려면 this.$store를 이용하여 getters에 접근해야 합니다.

    // TestVueComponent.vue : Parent
     
     
    <template>
      <div>
        <ul>
          <li>
            Parent Counter : {{ parentCounter }} <br>
            <button class="button_class" @click="addCounter">
              +
            </button>
            <button class="button_class" @click="subCounter">
              -
            </button>
            <child-vuex />
          </li>
        </ul>
      </div>
    </template>
     
    <script>
    import ChildVuex from '@components/kim/ChildVuex'
     
    export default {
      name: 'Child',
      components: {
        ChildVuex
      },
      computed: {
        parentCounter () {
          return this.$store.getters.getCounter
        }
      },
      methods: {
        addCounter () {
          this.$store.state.counter++
        },
        subCounter () {
          this.$store.state.counter--
        }
      }
    }
    </script>
     
     
     
    // ChildVuex.vue : Chiild
     
     
    <template>
      <div>
        <hr>
        Child counter : {{ childCounter }} <br>
        <button class="button_class">
          +
        </button>
        <button class="button_class">
          -
        </button>
      </div>
    </template>
     
    <script>
    export default {
      computed: {
        childCounter () {
          return this.$store.getters.getCounter
        }
      }
    }
    </script>

     

    이렇게 getters를 Vuex에 등록하고 사용하였습니다.

     

    참고로, computed의 장점인 Caching 효과는 단순히 state 값을 반환하는 것이 아니라, getters에 선언된 속성에서 filter(), reverse() 등의 추가적인 계산 로직이 들어갈 때 발휘됩니다.

     

     

     

     


    1. Mutations 란?

     

    Mutations 이란 Vuex의 데이터, 즉 state 값을 변경하는 로직들을 의미합니다.

    Getters와 차이점은 아래와 같습니다.

    1) 인자를 받아 Vuex에 넘겨줄 수 있습니다.

    2) computed가 아닌 methods에 등록합니다.

     

     

    Actions과의 차이점은 아래와 같습니다.

     1) Mutations는 동기적 로직을 정의

     2) Actions는 비동기적 로직을 정의

     

     

    Mutations의 성경상 안에 정의한 로직들이 순차적으로 일어나야 각 컴포넌트의 반영 여부를 재대로 추적할 수가 있기 때문입니다.

    지금까지 예제는 counter를 변경할 때,

     

    return this.$store.state.counter++

    return this.$store.state.counter--

     

    와 같이 컴포넌트에서 직접 state에 접근하여 변경하였지만,

    이는 안티패턴으로써 Vue의 Reactivity 체계와 상태관리 패턴에 맞지 않은 구현방식입니다.

    안티패턴인 이유는 여러 개의 컴포넌트에서 같은 state 값을 동시에 제어하게 되면,

    state값이 어느 컴포넌트에서 호출해서 변경된건지 추적하기가 어렵기 때문입니다.

     

    하지만, 상태 변화를 명시적으로 수행함으로써 테스팅, 디버깅, Vue의 Reactive 성질 준수의 혜텍을 얻습니다.

    아래와 같이 commit 을 이용하여 state를 변경합니다.

     

    Mutations가 낯설다면, 기억하기 쉽게 Setters로 이해해도 된다고 합니다.

     

     

    2. Mutaions 등록

     

    getters와 마찬가지로 Vuex에 mutations 속성을 추가합니다.

    export default new Vuex.Store({
      // ...
     
     
      mutations: {
        addCounter: function (state, payload) {
          return state.counter++
        }
      }
    })

     

     

     

    3. Mutations 사용

     

    상위 컴포넌트의 기존 코드는 addCounter 에서 state의 counter 값을 바로 접근하여 1을 올리는 코드였습니다.

    state를 컴포넌트에서 직접 접근하여 증가시키는 부분을 앞에서 등록했던 mutations를 이용하는 코드로 바꾸면 아래와 같습니다.

     

    // TestVueComponent.vue : Parent
     
     
    methods: {
      addCounter() {
        // this.$store.state.counter++;
        this.$store.commit('addCounter');
        console.log('state Counter : ' + this.$store.state.counter)
      }
    }

     

    getters 처럼 this.$store.mutations.addCounter

    이런식의 접근이 불가능하고, commit을 이용하여 mutations 이벤트를 호출해야 한다는 것입니다.

    앞서 설명한 추적 가능한 상태 변화를 위해 프레임워크가 이렇게 구조화가 되어 있다는 것을 알아두시면 좋을 것 같습니다.

     

     

     

    4. Mutations 결과

     

    정상적으로 state 값이 변경되는 것을 확인하였습니다.

     

     

     

     

    5. Mutations에 인자 값 넘기기

     

    각 컴포넌트에서 Vuex의 state를 조작하는데 필요한 특정 값들을 넘기고 싶을 때는 commit()에 두 번째 인자를 추가합니다.

     

    // TestVueComponent.vue : Parent
    addCounter () {
        this.$store.commit('addCounter', 10)
     // this.$store.commit('addCounter')
        console.log('state Counter : ' + this.$store.state.counter)
    }
     
    // store.js
    mutations: {
      addCounter: function (state, payload) {
        state.counter = payload
        return state.counter
        // return state.counter++
      }
    }

     

     

     

    6. Mutations 인자 값 결과 확인

     

    인자값으로 10을 넘겨, Vuex에 등록하게 하였습니다.

    결과는 10을 리턴받아 정상 출력하였습니다.

     

     

     


    출처: https://joshua1988.github.io/web-development/vuejs/vuex-getters-mutations/

     

    반응형

    댓글

Designed by black7375.