쇼핑 카트 기능

스토어에 cart 스테이트를 추가합니다.






 



// store/index.js

new Vuex.Store({
  state: {
    books: [],
    cart: []
  }
});

액션 추가

쇼핑 카트에 도서를 추가하는 액션을 정의합니다.

  1. 액션 실행과정에서 전달된 도서의 재고(inventory)가 있을 경우 조건문이 실행됩니다.
  2. 전달된 도서의 ID와 쇼핑 카트에 등록된 아이템의 ID와 비교하여 일치하는 도서가 있는지 검토합니다.
  3. 추가할 도서가 쇼핑 카트의 도서와 일치하지 않을 경우, 쇼핑 카트에 도서를 새롭게 추가합니다.
  4. 추가할 도서가 쇼핑 카트의 도서와 일치할 경우, 쇼핑 카트의 도서 수량을 증가합니다.
  5. 쇼핑 카트에 도서를 추가한 후, 도서의 재고를 감소시킵니다.







 
 
 
 
 
 
 
 
 
 
 



// store/index.js

new Vuex.Store({
  state: {
    cart: []
  },
  actions: {
    addBookToCart({state, commit}, book) {
      if ( book.inventory > 0 ) { // [1]
        const cartItem = state.cart.find(item => item.id === book.id); // [2]
        if (!cartItem) {
          commit('pushBookToCart', book.id); // [3]
        } else {
          commit('incrementItemQuantity', cartItem); // [4]
        }
        commit('decrementBookInventory', book); // [5]
      }
    }
  }
});

NOTE

Vuex의 뮤테이션은 상태를 변경하는 유일한 방법으로 단일 책임 원칙에 따라 작성합니다.

뮤테이션 추가

액션에서 실행하는 뮤테이션을 각각 정의 합니다.

  1. 쇼핑 카트에 도서를 추가하는 뮤테이션
  2. 쇼핑 카트의 아이템 수량을 증가시키는 뮤테이션
  3. 도서의 재고 수량을 감소시키는 뮤테이션

 





 


 




mutations: {
  pushBookToCart(state, bookId) { // [1]
    state.cart.push({
      id: bookId,
      quantity: 1
    });
  },
  incrementItemQuantity(state, cartItem) { // [2]
    cartItem.quantity++;
  },
  decrementBookInventory(state, book) { // [3]
    book.inventory--;
  }
}

카트 추가 버튼과 메서드

컴포넌트 도서 목록에 "카트 추가" 버튼 코드를 삽입한 후, addBookToCart 메서드를 실행하는 이벤트 구문을 추가합니다.









 
 
 
 




<!-- components/BookList.vue -->

<div class="book-list">
  <h1>도서 목록</h1>
  <img v-if="loading" src="https://i.imgur.com/JfPpwOA.gif" alt="로딩 중...">
  <ul v-else>
    <li v-for="(book,i) in books" :key="i">
      {{ book.name }} / {{ book.price | won }}
      <button
        type="button"
        @click="addBookToCart(book)"
      >카트 추가</button>
    </li>
  </ul>
</div>

addBookToCart 메서드를 추가한 후, 스토어의 addBookToCart 액션을 디스패치 하는 코드를 작성합니다.







 
 
 



// components/BookList.vue

export default {
  name: "BookList",
  // ...
  methods: {
    addBookToCart(book) {
      this.$store.dispatch("addBookToCart", book);
    }
  },
}

쇼핑 카트 기능 테스트

Vue Devtools의 Vuex 탭을 통해 뮤테이션 실행 기록을 살펴볼 수 있습니다.

  1. 컴포넌트 생성 과정에서 setBook 액션이 실행됩니다.
  1. 도서 목록의 첫번째 "카트 추가" 버튼을 누르면 액션이 수행된 결과를 살펴볼 수 있습니다.
  • pushBookToCart ➡︎ cart 배열에 선택된 아이템이 추가 됩니다.
  • decrementBookInventory ➡︎ 첫번째 도서의 재고가 -1 됩니다.
  1. 다시 한 번! 도서 목록의 첫번째 "카트 추가" 버튼을 누르고 결과를 살펴봅니다.
  • incrementItemQuantity ➡︎ 카트 아이템 수량이 +1 됩니다.
  • decrementBookInventory ➡︎ 첫번째 도서의 재고가 -1 됩니다.
  1. 도서 목록의 두번째 "카트 추가" 버튼을 누른 후 결과를 확인합니다.
  • pushBookToCart ➡︎ cart 배열에 선택된 아이템이 추가 됩니다.
  • decrementBookInventory ➡︎ 두번째 도서의 재고가 -1 되어 재고가 소진됩니다.

NOTE

"시간 여행(time travel)" 버튼을 클릭하면 뮤테이션 이벤트 기록 사이를 이동해 확인할 수 있습니다.