동적 Vuex 게터
고차 함수(Higher-order_function)를 사용해 Vuex에서 동적 게터를 만드는 방법을 살펴 보겠습니다. 동적 게터는 게터에 인자를 전달할 수 있습니다. 이런 방법은 인자를 전달해 스토어를 조회할 때 유용합니다.
일반적인 사용 예는 id
를 전달해 스테이트에서 아이템을 찾는 게터입니다.
getters: {
getBookById(state) {
return (id) => {
return state.books.find(book => book.id === id);
}
},
}
NOTE
화살표 함수를 사용해 다음과 같이 작성할 수도 있습니다.
getters: {
getBookById: state => id => state.books.find(book => book.id === id),
}
판매 가능한 도서만 표시하던 대신 '카트에 추가' 버튼을 비활성화 하는 방향으로 전환하기 위해
컴포넌트에 사용된 스토어의 availableBooks
코드를 제거하고, 모든 도서를 화면에 표시하도록
스토어의 books
스테이트로 변경합니다.
// components/BookList.vue
export default {
name: 'BookList',
computed: {
books() {
// return this.$store.getters.availableBooks;
return this.$store.state.books;
}
},
// ...
}
도서 재고가 없을 경우 품절(Out of Stock)로 버튼을 사용할 수 없도록 설정해봅니다.
버튼의 disabled
속성을 동적으로 설정하는 게터 checkOutOfStock
를 설정하고, 인자로 book
을 전달하는 코드를 작성합니다.
컴포넌트의 계산된 속성 checkOutOfStock
은 스토어의 checkOutOfStock
게터를 반환하도록 설정합니다.
<!-- components/BookList.vue -->
<template>
<div class="book-list">
<!-- ... -->
<ul v-else>
<li v-for="(book,i) in books" :key="i">
{{ book.name }} / {{ book.price | won }}
<button
type="button"
@click="addBookToCart(book)"
:disabled="checkOutOfStock(book)"
>카트에 추가</button>
</li>
</ul>
</div>
</template>
<script>
export default {
name: "BookList",
computed: {
checkOutOfStock() {
return this.$store.getters.checkOutOfStock;
}
},
}
</script>
NOTE
'Sold Out'과 'Out of Stock'의 의미는 다소 다릅니다.
용어 | 설명 |
---|---|
매진(sold out) | 판매 가능하지 않은 |
품절(out of stock) | (일시적으로) 재고가 없는 |
스토어에 checkOutOfStock
동적 게터를 추가한 후, 반환되는 함수의 매개변수로 도서(book
)을 설정합니다.
동적 게터를 통해 전달 받은 book
의 재고가 0일 경우 true
를 아닐 경우 false
를 반환합니다.
// store/index.js
getters: {
checkOutOfStock(state) {
return book => {
return book.inventory === 0;
}
},
}
NOTE
다음과 같이 코드를 변경할 수 있습니다.
getters: {
checkOutOfStock: state => book => book.inventory === 0
}
스토어의 addBookToCart
액션 코드에서도 동적 게터를 활용할 수 있습니다.
액션의 첫번째 인자에서 getters
를 추가한 후, 조건으로 동적 게터를 활용한 예입니다.
// store/index.js
actions: {
addBookToCart({state, getters, commit}, book) {
// if (book.inventory > 0) {
if (!getters.checkOutOfStock(book)) {
// ...
}
},
// ...
}