component props, emit
<div id="app">
<my-comp />
</div>
와 같은 구조로 작성하고 app에 Vue 인스턴스르 붙이면 컴포넌트간의 구조는 어떻게 될까? 여기선 app에 붙인 컴포넌트가 my-comp보다 상위 컴포넌트가 된다. 따라서, app에 붙은 컴포넌트를 vm이라고 하면 vm은 my-comp에게 props를 통해 데이터를 전달할 수 있다. 반대로 my-comp는 vm에게 데이터를 어떻게 전달할까?
답은 emit을 사용해서 전달한다. 데이터를 전달하는 것은 아니고 이벤트를 전달하게 된다.
아래 코드의 구조를 보면 my-comp를 만들 때 my-msg props에 vm의 message 값을 넘겨주기 위해서 :my-msg="message"를 사용했다.
반대로 my-comp에서 클릭을 발생했을 때 이벤트를 vm으로 넘겨주기 위해서 my-comp methods에 updateMsg를 선언하여 this.$emit('my-event', 'Good')을 적었다. 이를 통해 템플릿 코드에서 div가 클릭되면 updateMsg가 호출되고 updateMsg의 코드에서 emit을 통해 상위 컴포넌트로 이벤트를 전달한다. 이를 받아주기 위해서 html 코드 상에 @my-event="handle"을 적었다.
따라서 vm은 my-event가 emit을 통해 상위컴포넌트로 올라오면 이를 위한 핸들러 handle함수를 호출한다.
정리하면 emit을 사용하기 위한 방식은 다음과 같다.
1. 하위 컴포넌트에서 template 코드에 이벤트에 대한 핸들러를 등록
<div @click="updateMsg"> </div>
2. 하위 컴포넌트에서 이벤트 핸들러 함수에 emit을 사용
updateMsg(){ this.$emit('my-event', 'Good') }
3. 하위 컴포넌트를 만들 때 @하위 컴포넌트의 이벤트 핸들러 함수 = 상위 컴포넌트 이벤트 핸들러 함수
<my-comp @my-event="handle"
4. 상위 컴포넌트 이벤트 핸들러 함수에서 해당 이벤트 처리
handle(value){ this.message = value}
위 코드를 따라치면서 emit을 사용하기 위한 흐름을 따라가면 이해가 될 것이다. v-on과 v-bind에 대해서 잘 알고 있어야 이해가 쉽다.