52. Callback Functions
npm create vue@latest
이 강의에서는 자식 컴포넌트에서 부모 컴포넌트로 데이터를 업데이트하는 대안적인 방법으로 콜백 함수를 사용하는 방법을 배웁니다.
요약하면 다음과 같습니다:
- 이벤트 발생(event emit)은 자식 컴포넌트에서 부모 컴포넌트로 데이터를 업데이트하는 가장 좋은 방법이지만, 콜백 함수를 사용하는 것도 유용한 방법입니다.
App
컴포넌트에서UpdateAgeCB
라는 새로운 메소드를 생성합니다.
이 메소드는 기존UpdateAge
함수와 동일한 기능을 수행합니다.UpdateAgeCB
함수를User
컴포넌트로 전달합니다.
함수, 객체, 배열 등도props
로 전달할 수 있습니다.User
컴포넌트에서 콜백 함수를prop
으로 받아들여 템플릿에서 사용합니다.
여기서는 버튼 클릭시 콜백 함수를 직접 호출합니다.- 콜백 함수를 사용할 때는 자식 컴포넌트가 부모 컴포넌트의 함수를 호출하는 것으로, 데이터 변경은 부모 컴포넌트에서 발생합니다.
- 콜백 함수와 이벤트 발생 중 어느 것을 사용할지는 선호도에 따라 다릅니다.
성능 측면에서는 두 방법 모두 비슷합니다. - Vue는 이벤트 발생을 권장합니다. 대부분의 문서와 튜토리얼에서 이벤트를 사용하여 데이터를 전달하는 방법을 사용합니다.
- 이벤트 발생의 주요 장점 중 하나는 Vue 개발자 도구의 타임라인 도구를 사용하여 이벤트의 세부 사항을 디버깅할 수 있다는 것입니다.
- 반면에 콜백 함수를 사용할 때는 이벤트가 기록되지 않아 디버깅이 어려울 수 있습니다.
이 강의를 통해 부모 컴포넌트로 데이터를 업데이트하는 두 가지 방법, 즉 콜백 함수와 이벤트 발생을 배웠습니다.
App.vue
<script lang="ts">
import Greeting from "@/components/Greeting.vue";
import User from "@/components/User.vue";
export default {
name: 'App',
components: {
Greeting,
User,
},
data() {
return {
age: 20,
}
},
methods: {
updateAge(num: number) {
this.age += num;
},
updateAgeCB(num: number) {
this.age += num;
}
}
}
</script>
<template>
<p>App.vue</p>
<Greeting :age="age" />
<User :age="age" @age-change="updateAge" :age-change-fn="updateAgeCB" />
</template>
User.vue
<script lang="ts">
export default {
name: 'User',
props: {
age: {
type: Number,
required: true,
// default: 20,
validator(value: number) {
return value < 130;
}
},
ageChangeFn: {
type: Function,
required: true,
}
},
emits: ['age-change'],
computed: {
ageDoubled() {
return this.age * 2;
}
},
methods: {
onClickAge() {
this.$emit('age-change', 3)
}
}
}
</script>
<template>
<button type="button" @click="onClickAge">Update Age Event</button>
<button type="button" @click="ageChangeFn(3)">Update Age CB</button>
<p>The user is {{ age }} years old</p>
<p>{{ ageDoubled }}</p>
</template>
<style scoped>
</style>
Greeting.vue
<script lang="ts">
export default {
name: 'Greeting',
props: ['age'],
data() {
return {
msg: 'Hello World!'
}
}
}
</script>
<template>
<p v-if="age > 25">{{ msg }}</p>
<p v-else>You must be 25 years or older to view this message</p>
</template>
<style scoped lang="scss">
p:hover {
color: darken(#cc4444, 15%);
}
</style>
main.ts
import { createApp } from 'vue'
import { createPinia } from 'pinia'
import App from '@/App.vue';
import router from './router'
const app = createApp(App)
app.use(createPinia())
app.use(router)
app.mount('#app')