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%’ 할인된 가격이 표시됩니다.
이번에는 커밋(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%’의 할인이 적용된 가격이 표시됩니다.