자식 –> 부모 의 통신
앞에서 부모에서 자식으로의 통신은 단순히 props를 넘겨주면 되었다. 이번에는 반대의 경우이다. 자식에서 부모로의 통신을 할려면 어떻게 해야 하는가이다.
리액트에서는 콜백펑션을 props로 내려주고 호출하는 방법을 사용하지만 vue는 많은 방법들이 존재한다. 여기서는 리액트쪽보다 앵규러에서 사용하는 방법을 사용한다. 하위 컴포넌트에서 이벤트를 발생시키고 부모 컴포넌트에서는 해당 이벤트를 캐치하는 방법이다.
- 부모
1 |
<product :premium="premium" @add-to-cart="updateCart"></product> |
- 자식
1 |
this.$emit('add-to-cart'); |
현재는 상품마다 각각 cart를 갖고 있는데, 실제는 cart를 하나를 갖고 있고 해당 cart에 상품을 담는 구조라야 한다. product 에 포함된 cart를 떼어내어 바로위 부모인 Vue Instance에 이동시킨다. cart 속성도 떼어내서 Vue instance data 속성으로 이동시킨다.
1 2 3 4 5 6 7 8 |
... <div id="app"> <div class="cart"> <p>Cart({{ cart }})</p> </div> <product :premium="premium" @add-to-cart="updateCart"></product> </div> ... |
product 컴포넌트에서 add cart를 누르면 $emit로 이벤트를 발생시키고 부모에서 해당 이벤트를 listen하는 코드를 작성한다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
... methods: { addToCart() { this.$emit('add-to-cart'); }, updateProduct(index) { this.selectedVariant = index; } } }); var app = new Vue({ el: '#app', data: { premium: true, cart: 0 }, methods: { updateCart() { this.cart += 1; } } }); |
카트에 단순히 숫자만 증가하면 어떤 상품이 담겨있는지 알수가 없으므로 add to cart 버튼을 누르면 product의 id를 파라메터로 상품 id를 표시하게 해보자.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
... }, methods: { addToCart() { this.$emit('add-to-cart', this.variants[this.selectedVariant].variantId); }, updateProduct(index) { this.selectedVariant = index; } } }); var app = new Vue({ el: '#app', data: { premium: true, cart: [] }, methods: { updateCart(id) { this.cart.push(id); } } }); |
+ todo
remove from cart 버튼을 product 에 추가한다.
해당 버튼을 누르면 remove-from-cart 이벤트와 product id를 emit 하고 부모 컴포넌트에서 이 이벤트를 수신하여 해당 상품 id를 cart 배열에서 제거한다.
See the Pen Challenge 9 – Intro to Vue by Gregg Pollack (@GreggPollack) on CodePen.0