완벽하게 Vue.js
[Vue.js][Ch2][Vue 문법] 컴포넌트 - Emit
써치킴
2022. 4. 18. 20:37
Emit
다른 컴포넌트에게 이벤트를 전달하기 위해 사용.
특정한 이벤트를 상속받아서 emits 옵션에 연결해서 사용.
1. emits 속성에 click 이벤트를 컴포넌트 내부에서 사용할 것이라고 정의
<script>
export default {
emits: [
'click' // 부모 요소의 click 이벤트를 컴포넌트 내부에서 사용할 것이라고 정의
]
}
</script>
2. click 이벤트를 어떤 부분에 연결할 것인지 정함 -> h1 요소에 연결하겠음
<template>
<div class="btn">
<slot></slot>
</div>
<!-- h1 태그를 클릭하면 $emit을 통해서 부모 요소에 연결되어 있는 @click 이벤트 실행 -->
<h1 @click="$emit('click')">
ABC
</h1>
</template>
- h1 태그를 클릭하면 emit 메소드를 실행하겠다.
부모 요소의 click 이벤트를 가져와서 emits 속성에 명시 -> 명시된 내용을 요소의 emit 부분에 명시
App.vue
<template>
<MyBtn @click="log">
Banana
</MyBtn>
</template>
<script>
import MyBtn from '~/components/Ex15_MyBtn'
export default {
components: {
MyBtn
},
methods: {
log() {
console.log('Click!');
}
}
}
</script>
MyBtn.vue
<template>
<div class="btn">
<slot></slot>
</div>
<!-- h1 태그를 클릭하면 $emit을 통해서 부모 요소에 연결되어 있는 @click 이벤트 실행 -->
<h1 @click="$emit('click')">
ABC
</h1>
</template>
<script>
export default {
emits: [
'click' // 부모 요소의 click 이벤트를 컴포넌트 내부에서 사용할 것이라고 정의
]
}
</script>
<style scoped lang="scss">
.btn {
display: inline-block;
margin: 4px;
padding: 6px 12px;
border-radius: 4px;
background-color: gray;
color: white;
cursor: pointer;
&.large {
font-size: 20px;
padding: 10px 20px;
}
}
</style>
출력
Banana를 클릭하면 아무런 동작이 없지만
ABC를 클릭하면 Click!이 콘솔에 출력된다.
컴포넌트에 연결하는 이벤트는 실제로 사용하는 이벤트가 아니여도 상관없다.
@click -> @searchkim 으로 사용 가능하다.
요소에 실제 동작하는 이벤트도 사용 가능하다.
<template>
<div class="btn">
<slot></slot>
</div>
<!-- h1 태그를 더블클릭하면 $emit을 통해서 부모 요소에 연결되어 있는 @searchkim 이벤트 실행 -->
<h1 @dblclick="$emit('searchkim')">
ABC
</h1>
</template>
@dlbclick 이벤트 사용 -> 더블 클릭을 하면 콘솔에 Click!가 출력된다.
event 객체를 사용하려면
$emit 메소드에 event 객체를 인수로 전달
App.vue
<template>
<MyBtn @searchkim="log">
Banana
</MyBtn>
</template>
<script>
import MyBtn from '~/components/Ex15_MyBtn'
export default {
components: {
MyBtn
},
methods: {
log(event) {
console.log('Click!');
console.log(event);
}
}
}
</script>
MyBtn.vue
<template>
<div class="btn">
<slot></slot>
</div>
<!-- h1 태그를 클릭하면 $emit을 통해서 부모 요소에 연결되어 있는 @searchkim 이벤트 실행 -->
<h1 @dblclick="$emit('searchkim', $event)">
ABC
</h1>
</template>
<script>
export default {
emits: [
'searchkim' // 부모 요소의 searchkim 이벤트를 컴포넌트 내부에서 사용할 것이라고 정의
]
}
</script>
<style scoped lang="scss">
.btn {
display: inline-block;
margin: 4px;
padding: 6px 12px;
border-radius: 4px;
background-color: gray;
color: white;
cursor: pointer;
&.large {
font-size: 20px;
padding: 10px 20px;
}
}
</style>
출력
특정 요소가 변경될때마다 그 내용을 App.vue에서 확인하고 싶다면?
양방향 데이터 바인딩 구조에서 emit 사용
App.vue
<template>
<!-- html의 속성을 작성할때는 대시 케이스 사용(change-msg) -->
<MyBtn
@searchkim="log"
@change-msg="logMsg">
Banana
</MyBtn>
</template>
<script>
import MyBtn from '~/components/Ex15_MyBtn'
export default {
components: {
MyBtn
},
methods: {
log(event) {
console.log('Click!');
console.log(event);
},
logMsg(msg) {
console.log(msg);
}
}
}
</script>
MyBtn.vue
<template>
<div class="btn">
<slot></slot>
</div>
<!-- h1 태그를 클릭하면 $emit을 통해서 부모 요소에 연결되어 있는 @click 이벤트 실행 -->
<h1 @dblclick="$emit('searchkim', $event)">
ABC
</h1>
<input
type="text"
v-model="msg" /> <!-- 양방향 데이터 바인딩 -->
</template>
<script>
export default {
emits: [
'searchkim', // 부모 요소의 searchkim 이벤트를 컴포넌트 내부에서 사용할 것이라고 정의
'changeMsg' // changeMsg 이벤트를 사용하겠다 명시
],
data() {
return {
msg: ''
}
},
watch: {
msg() { // msg 감시
// input 요소에 데이터를 입력할 때마다 this.$emit을 통해서 this.msg 인수와 함께 changeMsg 실행
this.$emit('changeMsg', this.msg);
}
}
}
</script>
<style scoped lang="scss">
.btn {
display: inline-block;
margin: 4px;
padding: 6px 12px;
border-radius: 4px;
background-color: gray;
color: white;
cursor: pointer;
&.large {
font-size: 20px;
padding: 10px 20px;
}
}
</style>
출력
input 요소에 데이터를 입력할 때마다 msg 데이터가 양방향 데이터 방식으로 갱신되는 구조이고, watch 옵션을 통해 감시한다.
watch 옵션에서 실행되는 명령은 $emit 메소드를 통해 changeMsg 이벤트가 발생하고, 명시해놓은 logMsg가 발생한다.