🌱 emit
: props(상위에서 하위로)의 반대 개념.
: 하위(자식)컴포넌트에서 상위(부모)컴포넌트로 데이터, 이벤트를 전달하는 방식.
: 상위 컴포넌트에서 하위 컴포넌트의 특정 이벤트가 발생하기를 기다렸다가 하위 컴포넌트에서 특정 이벤트 발생 시 상위 컴포넌트에서 해당 이벤트를 수신하여 상위 컴포넌트의 메서드를 호출하는 것.
// 이벤트 발생
this.$emit('이벤트명');
// 이벤트 수신
<child-component v-on:이벤트명='상위 컴포넌트의 메서드 명'></child-component>
👩💻 $emit()을 호출하면 괄호 안에 정의된 이벤트가 발생함.
👩💻 일반적으로 $emit()을 호출하는 위치는 하위 컴포넌트의 특정 메서드 내부임.
∴ $emit()을 호출할 때 사용하는 this는 하위 컴포넌트를 의미함.
👩💻 호출한 이벤트는 하위 컴포넌트를 등록하는 태그(상위 컴포넌트의 template 속성에 위치)
에서 v-on으로 받는다. 하위 컴포넌트에서 발생한 이벤트 명을 v-on:속성에 지정하고,
속성의 값에 이벤트가 발생했을 때 호출될 상위 컴포넌트의 메서드를 지정한다.
👉 $emit 적용 예시
...
<div id='test'>
<child-component v-on:show-log='printText'></child-component>
<!--show-log=하위 컴포넌트 이벤트명 / printText=상위 컴포넌트 이벤트명 -->
</div>
...
<script>
Vue.component('child-component',{
template: '<button @click='showLog'>보기</button>',
methods: { // 메소드 추가
showLog: function(){
// 이벤트 발생 로직 $emit(~)
this.$emit('show-log');
}
}
});
const test = new Vue({
el: '#test',
data: {
message: '안녕하세요~~~!!'
},
methods: {
printText: function(){
console.log('이벤트 발생')
}
}
});
</script>
👩💻 1) [보기]버튼을 클릭하면 @click='showLog'에 따라 showLog()메서드 실행됨.
2) showLog()메서드 안의 this.$emit('show-log')가 실행되면서 이벤트 발생.
3) show-log이벤트는 <child-component/>에 정의한 @show-log에 전달되고,
@show-log의 대상 메서드인 최상위 컴포넌트의 메서드 printText()가 실행됨
4) printText()는 '이벤트 발생'이라는 로그를 콘솔에 출력함.
<!-- 하위(자식) 컴포넌트 -->
<input type="text" :value = "title" @input = "titleUpdate"
style = "padding: 20px; border: 1px pink solid">
...
<script>
methods : {
titleUpdate(e) {
this.$emit('titleFromChild', e.target.value)
// 첫번째 인자는 부모 컴포넌트에서 자식 컴포넌트를 호출할때 적을 메서드 이름,
// 두번째 인자는 해당 메서드에 들어갈 값으로 지정
}
}
</script>
<!-- 상위(부모) 컴포넌트 -->
<template>
<div>
<h1>Welcome to Home</h1>
<inputField :title = "title" @titleFromChild="titleChange"/>
<!-- 부모 컴포넌트에서 자식 컴포넌트를 호출하는 부분에
@메서드 이름으로 부모의 메서드와 바인딩을 시켜줌 -->
{{ title }}
</div>
</template>
<script>
date() {
return {
title : ""
}
},
...,
methods: {
titleChange(title) {
this.title = title
}
}
</script>
👩💻 부모 컴포넌트에서 새로 생성한 titleChange 메서드는 부모의 this.title 값을
titleChange 메서드가 titleFromChild 메서드로부터 받아오는 인자값 title로
지정해주게 된다.
:부모와 자식 컴포넌트에 각각 메서드를 작성하고 사용할 필요없이, 자식 컴포넌트에서 정의한 $emit을 바로 부모로 넘겨주는 방법도 있다.
<!-- 하위 컴포넌트 -->
<template>
<div>
<form>
<label>ID</label>
<input type="text" :value = "title" @input = "$emit('titleFromChild', $event)" style = "padding: 20px; border: 1px pink solid">
<button>Submit</button>
</form>
</div>
</template>
<script>
export default {
props : {
title : {
type : String,
required : true
}
},
// methods : {
// titleUpdate(e) {
// this.$emit('titleFromChild', e.target.value)
// }
// }
}
</script>
👩💻 기존 titleUpdate 메서드는 주석처리 해버리고, @input 속성에 $emit을 직접 작성함.
여기서 두번째 인자로 받는 전달해줄 값은 $event로 지정.
<!-- 상위 컴포넌트 -->
<template>
<div>
<h1>Welcome to Home</h1>
<inputField :title = "title" @titleFromChild="title = $event.target.value"/>
{{ title }}
</div>
</template>
<script>
import inputField from '@/components/layout/inputField';
export default {
data() {
return {
title : ""
}
},
components : {
inputField
},
// methods: {
// titleChange(title) {
// this.title = title
// }
// }
}
</script>
👩💻 부모 컴포넌트에서도 역시나 method를 주석처리하고, 자식 컴포넌트인 inputField 호출
부분에 자식 컴포넌트에서 정의한 titleFromChild 메서드를 속성으로 달아아줌.
그리고 여기서 바로 title 값을 $event.target.value 값으로 지정해줌.
처리 완료 후 실행 시 정상작동 되는 것을 확인할 수 있음.
참조 👈 click