50. Emitting Events
npm create vue@latest
이 강의에서는 자식 컴포넌트에서 props를 업데이트하는 방법에 대해 배우게 됩니다. 요약하면 다음과 같습니다:
- 자식 컴포넌트에서 props를 직접 업데이트하는 것은 허용되지 않습니다.
이는 애플리케이션에서 버그와 예상치 못한 동작을 초래할 수 있습니다. - 이 문제를 해결하기 위해 이벤트를 발생시키는 것을 사용합니다.
Vue는 이를 위해 특별한 함수를 제공합니다. - User 컴포넌트에서 클릭 이벤트를 통해 사용자 정의 이벤트
age-change
를 발생시킵니다. - 부모 컴포넌트인 App에서 이 이벤트를 수신하여 연령을 업데이트합니다.
- 이벤트 수신시 함수를 실행하여 age 값을 변경합니다.
- 이벤트를 통해 데이터를 전달할 수 있으며, 예를 들어
age-change
이벤트에 숫자 3을 전달하여 age를 3씩 증가시킬 수 있습니다. - User 컴포넌트에서는
emits
옵션을 사용하여 어떤 이벤트가 발생할 수 있는지 명시합니다. - props는 읽기 전용 값으로 사용하는 것이 좋으며, 계산된 속성이나 메소드에서 활용할 수 있습니다.
- 예를 들어, User 컴포넌트에서 age의 두 배 값을 계산하여 표시할 수 있습니다.
이 경우에는 age 값을 변경하지 않고 사용하기 때문에 오류가 발생하지 않습니다.
이 강의를 통해 자식 컴포넌트에서 부모 컴포넌트로 데이터를 업데이트하는 방법과, 이벤트를 통해 데이터를 전달하는 방법을 배웠습니다.
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) {
this.age += num;
}
}
}
</script>
<template>
<p>App.vue</p>
<Greeting :age="age" />
<User :age="age" @age-change="updateAge" />
</template>
User.vue
<script lang="ts">
export default {
name: 'User',
props: ['age'],
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</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')