HEROPY
Tech
Vuex - 4 - Mutations / Payload
{{ scrollPercentage }}%

Vuex - 4 - Mutations / Payload

jsvuevuex

Vuex Mutations

Vuex 변이(Mutations)는 저장소의 상태(State)를 변경하는 방법입니다.

과일의 가격을 할인하는 버튼을 추가하여 변이(Mutations)를 적용해 보겠습니다.
버튼을 사용하기 위해 src/components 디렉토리에 BtnDiscount.vue 컴포넌트를 추가합니다.

vue-simple-app
  #...
  ├─src
  │  ├─assets
  │  ├─components
  │  │  ├─BtnDiscount.vue
  │  │  ├─FruitsList.vue
  │  │  └─FruitsPrice.vue
  │  ├─css
  │  └─store
  #...

약간의 스타일이 추가된 버튼(BtnDiscount.vue) 컴포넌트를 만들어 줍니다.

<!--BtnDiscount.vue-->
<template>
  <div class="btn">DISCOUNT PRICE</div>
</template>

<script>
  export default {

  }
</script>

<style scoped>
  .btn {
    max-width: 700px;
    margin: 10px auto;
    padding: 10px 0;
    color: white;
    text-align: center;
    background: salmon;
    border-radius: 6px;
    cursor: pointer;
  }
</style>

App.vue에서 버튼 컴포넌트를 사용합니다.

<!--App.vue-->
<template>
  <div id="app">
    <h1 id="app-title">Fruits List</h1>
    <div id="fruits-table">
      <fruits-list></fruits-list>
      <fruits-price></fruits-price>
    </div>
    <btn-discount></btn-discount>
  </div>
</template>

<script>
import FruitsList from './components/FruitsList.vue';
import FruitsPrice from './components/FruitsPrice.vue';
import BtnDiscount from './components/BtnDiscount.vue';

export default {
  // ...
  components: {
    'fruits-list': FruitsList,
    'fruits-price': FruitsPrice,
    'btn-discount': BtnDiscount
  }
}
</script>

<!-- ... -->

화면에 ‘Discount Price’ 버튼이 추가되었습니다.

버튼 컴포넌트가 적용된 상태

저장소 상태를 변형하기 위해 mutations 속성에 현재 과일 가격의 ‘10%’를 할인하는 discountPrice 함수를 추가합니다.

// store.js
// ...
export const store = new Vuex.Store({
  state: {
    // ...
  },
  getters: {
    // ...
  },
  mutations: {
    discountPrice(state) {
      state.fruits.forEach(fruit => {
         fruit.price *= .9;
      });
    }
  }
});

discountPrice 변이를 적용할 수 있도록 버튼 컴포넌트(BtnDiscount.vue)에 클릭 이벤트를 추가하겠습니다.
변이 핸들러는 직접 호출할 수 없으므로 아래와 같이 commit 메소드를 이용하여 호출해야 합니다.

<!--BtnDiscount.vue-->
<template>
  <div class="btn" @click="discountPrice">DISCOUNT PRICE</div>
</template>

<script>
  export default {
    methods: {
      discountPrice() {
        this.$store.commit('discountPrice');
      }
    }
  }
</script>

<!-- ... -->

‘DISCOUNT PRICE’ 버튼을 누르면 현재 가격의 ‘10%’ 할인된 가격이 표시됩니다.

할인 버튼을 눌렀을 때

Payload

이번에는 커밋(Commit)에서 할인율을 입력할 수 있도록 페이로드(Payload)라고 하는 인자를 사용하여 호출하겠습니다.
할인율을 적용하면서 호출하도록 코드를 수정하겠습니다.
‘20%’를 할인하도록 적용하겠습니다.

<!--BtnDiscount.vue-->
<template>
  <div class="btn" @click="discountPrice">DISCOUNT PRICE</div>
</template>

<script>
  export default {
    methods: {
      discountPrice() {
        this.$store.commit('discountPrice', {
          discountRate: 20
        });
      }
    }
  }
</script>

<!-- ... -->

값이 어떤 의미를 가지고 페이로드로써 전달되는지 정확하게 나타내기 위해 페이로드를 객체로 작성합니다.

대부분의 경우 페이로드는 여러 필드를 포함할 수 있는 객체여야 하며 기록된 변이는 더 이해하기 쉽습니다.

이제 저장소의 변이가 인자를 받도록 수정합니다.

// store.js
// ...
export const store = new Vuex.Store({
  state: {
    // ...
  },
  getters: {
    // ...
  },
  mutations: {
    discountPrice(state, payload) {
      state.fruits.forEach(fruit => {
         fruit.price *= (100 - payload.discountRate) / 100;
      });
    }
  }
});

잘 적용되었다면 버튼을 클릭할 때마다 ‘20%’의 할인이 적용된 가격이 표시됩니다.

공지 이미지
이 내용을 72시간 동안 안 보고 싶어요!?