[Vue.js] Props์ Emits
Vue.js์ ์ปดํฌ๋ํธ ์์คํ ์ ์ ํ๋ฆฌ์ผ์ด์ ์ ์ฌ์ฌ์ฉ ๊ฐ๋ฅํ ์์ ๋จ์๋ก ๋๋ ์ ์๋๋ก ๋์์ค๋๋ค.
์ด ๊ณผ์ ์์ ๋ถ๋ชจ์ ์์ ์ปดํฌ๋ํธ ๊ฐ์ ๋ฐ์ดํฐ ์ ๋ฌ๊ณผ ์ด๋ฒคํธ ์ฒ๋ฆฌ๊ฐ ์ค์ํฉ๋๋ค.
Vue3์ <script setup> ๋ฌธ๋ฒ์ ๊ธฐ์ค์ผ๋ก Props์ Emits์ ๋ํด์ ์ค๋ช ํ๋๋ก ํ๊ฒ ์ต๋๋ค.
1. Props ( ๋ถ๋ชจ์์ ์์์ผ๋ก ๋ฐ์ดํฐ ์ ๋ฌ ) ๐จ ๐ ๐ฆ
Props๋ ๋ถ๋ชจ ์ปดํฌ๋ํธ์์ ์์ ์ปดํฌ๋ํธ๋ก ๋ฐ์ดํฐ๋ฅผ ์ ๋ฌํ ๋ ์ฌ์ฉํฉ๋๋ค.
์์ ์ปดํฌ๋ํธ์์ ์ด๋ค ๋ฐ์ดํฐ๋ฅผ ๋ฐ์ ๊ฒ์ธ์ง ๋ช ์์ ์ผ๋ก ์ ์ํด์ผํฉ๋๋ค.
1-1. ๋ถ๋ชจ ์ปดํฌ๋ํธ
<template>
<div>
<h1>๋ถ๋ชจ ์ปดํฌ๋ํธ</h1>
<ChildComponent :msg="message" />
</div>
</template>
<script setup>
import ChildComponent from './ChildComponent.vue'
const message = '์๋
ํ์ธ์. ์ ๋ ๋ถ๋ชจ ์ปดํฌ๋ํธ์์ ์์ด์!'
</script>
1-2. ์์ ์ปดํฌ๋ํธ
<template>
<div>
<h2>์์ ์ปดํฌ๋ํธ</h2>
<p>{{ msg }}</p>
</div>
</template>
<script setup>
import { defineProps } from 'vue'
// ๋ถ๋ชจ๋ก๋ถํฐ ์ ๋ฌ๋ฐ์ props๋ฅผ ์ ์
const props = defineProps({
msg: {
type: String,
required: true,
},
})
</script>
๊ฒฐ๊ณผ
๋ถ๋ชจ ์ปดํฌ๋ํธ์ ๋ฉ์์ง๊ฐ ์์ ์ปดํฌ๋ํธ๋ก ์ ๋ฌ๋์ด ํ๋ฉด์ ์ถ๋ ฅ๋ฉ๋๋ค.
defineProps๋ Vue3์ <script setup>๋ฌธ๋ฒ์์ ๋ถ๋ชจ ์ปดํฌ๋ํธ๋ก๋ถํฐ ์ ๋ฌ๋ฐ๋ ๋ฐ์ดํฐ๋ฅผ ์ ์ธํ๋ ํจ์์ ๋๋ค. ์ปดํฌ๋ํธ์ Props๋ฅผ ๋ช ์์ ์ผ๋ก ์ ์ํ๋ฉฐ, ์ด ์ปดํฌ๋ํธ์์ ์ด๋ค Props๋ฅผ ์ฌ์ฉํ ์ง ์๋ ค์ฃผ๋ ์ญํ ์ ํฉ๋๋ค. ๊ทธ๋์ props๋ฅผ ์ฌ์ฉํ๊ธฐ ์ํด์ ์์ ๊ฐ์ด defineProps๋ฅผ ๋ช ์์ ์ผ๋ก ์ ์ด์ฃผ์ ์ผ ํฉ๋๋ค.
msg => props ์ด๋ฆ์ ๋๋ค. ๋ถ๋ชจ ์ปดํฌ๋ํธ๊ฐ ๋ฐ์ดํฐ๋ฅผ ์ ๋ฌํ ๋ :msg="message"์ ๊ฐ์ด ์ฌ์ฉํ์์ผ๋ฏ๋ก ์์ ์ปดํฌ๋ํธ์์ ์ฌ์ฉํ ๋๋ msg๋ฅผ ์ฌ์ฉํ๋ฉด ๋ฉ๋๋ค.
type: String => props์ ๋ฐ์ดํฐ ํ์ ์ ์ง์ ํฉ๋๋ค. ์ฌ๊ธฐ์ String์ msg๊ฐ ๋ฌธ์์ด์ด์ด์ผ ํ๋ค๋ ๊ฒ์ ์๋ฏธํฉ๋๋ค.
๋ง์ฝ type์ ๋ง์ง ์๋ ๋ฐ์ดํฐ๋ฅผ ์ ๋ฌํ๋ฉด ๊ฐ๋ฐ ์ฝ์์ ๊ฒฝ๊ณ ๊ฐ ์ถ๋ ฅ๋ฉ๋๋ค
required: true => props๊ฐ ํ์์ ์ผ๋ก ์ ๋ฌ๋์ด์ผ ํจ์ ๋ํ๋ ๋๋ค.
๋ง์ฝ ๋ถ๋ชจ ์ปดํฌ๋ํธ๊ฐ ์ด ๊ฐ์ ์ ๋ฌํ์ง ์์ผ๋ฉด ๊ฐ๋ฐ ์ฝ์์์ ๊ฒฝ๊ณ ๊ฐ ๋ฐ์ํฉ๋๋ค.
2. Emits ( ์์์์ ๋ถ๋ชจ๋ก ๋ฐ์ดํฐ ์ ๋ฌ ) ๐ฆ ๐ ๐จ
Emits๋ ์์ ์ปดํฌ๋ํธ๊ฐ ํน์ ์ด๋ฒคํธ๋ฅผ ๋ฐ์์์ผ ๋ถ๋ชจ ์ปดํฌ๋ํธ๊ฐ ์ด๋ฅผ ์ฒ๋ฆฌํ ์ ์๋๋ก ํฉ๋๋ค.
์์ ์ปดํฌ๋ํธ๊ฐ ์ง์ ๋ถ๋ชจ ๋ฐ์ดํฐ๋ฅผ ์์ ํ์ง ์๊ณ , ์ด๋ฒคํธ๋ฅผ ํตํด ๋ฐ์ดํฐ๋ฅผ ์ ๋ฌํ๋ ๋ฐฉ์์ ๋๋ค.
2-1. ๋ถ๋ชจ ์ปดํฌ๋ํธ
<template>
<div>
<h1>๋ถ๋ชจ ์ปดํฌ๋ํธ</h1>
<ChildComponent @custom-event="handleEvent" />
</div>
</template>
<script setup>
import ChildComponent from './ChildComponent.vue'
const handleEvent = (data) => {
alert(`์์ ์ปดํฌ๋ํธ๋ก๋ถํฐ ์ ๋ฌ๋ฐ์ ๋ฐ์ดํฐ: ${data}`)
}
</script>
2-2. ์์ ์ปดํฌ๋ํธ
<template>
<div>
<h2>์์ ์ปดํฌ๋ํธ</h2>
<button @click="sendEvent">์ด๋ฒคํธ ๋ฐ์์ํค๊ธฐ</button>
</div>
</template>
<script setup>
import { defineEmits } from 'vue'
// ๋ฐ์์ํฌ ์ด๋ฒคํธ ์ ์
const emit = defineEmits(['custom-event'])
const sendEvent = () => {
emit('custom-event', '์๋
ํ์ธ์. ์์ ์ปดํฌ๋ํธ์์ ์์ด์!')
}
</script>
๊ฒฐ๊ณผ
์์ ์ปดํฌ๋ํธ์์ ๋ฒํผ์ ํด๋ฆญํ๋ฉด ์ด๋ฒคํธ๊ฐ ๋ฐ์ํ๊ณ , ๋ถ๋ชจ ์ปดํฌ๋ํธ๊ฐ ํด๋น ์ด๋ฒคํธ๋ฅผ ์ฒ๋ฆฌํ์ฌ ์๋ฆผ์ ๋์๋๋ค.
defineEmits๋ Vue3์ <script setup> ๋ฌธ๋ฒ์์ ์์ ์ปดํฌ๋ํธ๊ฐ ๋ถ๋ชจ ์ปดํฌ๋ํธ์ ์ด๋ฒคํธ๋ฅผ ์ ๋ฌํ ๋ ์ฌ์ฉํ๋ ํจ์์ ๋๋ค. emit์ ํตํด ์์ ์ปดํฌ๋ํธ๋ ํน์ ์ด๋ฒคํธ๋ฅผ ๋ฐ์์์ผ ๋ถ๋ชจ ์ปดํฌ๋ํธ์์ ํด๋น ์ด๋ฒคํธ๋ฅผ ์ฒ๋ฆฌํ ์ ์์ต๋๋ค.
defineEmits๋ฅผ ํตํด ์์ ์ปดํฌ๋ํธ๋ ํน์ ์ด๋ฒคํธ๋ฅผ ์ ์( ์์ ์ฝ๋์์ 'custom-event' )ํ๊ณ , ์ด๋ฅผ emit์ผ๋ก ๋ถ๋ชจ์๊ฒ ์ ๋ฌํฉ๋๋ค. emit ํจ์์ ๋ ๋ฒ์งธ ์ธ์๋ ๋ถ๋ชจ์๊ฒ ์ ๋ฌํ ๋ฐ์ดํฐ์ด๋ฉฐ ๊ฐ์ฒด, ๋ฐฐ์ด, ๋ฌธ์์ด ๋ฑ ์ด๋ค ํํ๋ ๊ฐ๋ฅํฉ๋๋ค.
๊ทธ๋ผ ๋ถ๋ชจ ์ปดํฌ๋ํธ์์๋ @์ด๋ฒคํธ๋ช ( ์์ ์ฝ๋์์ 'custom-event' ) = "ํจ์"๋ฅผ ์ฌ์ฉํด ์ด๋ฒคํธ๋ฅผ ์์ ํ๊ณ , ์ ๋ฌ๋ ๋ฐ์ดํฐ๋ฅผ ์ฒ๋ฆฌํฉ๋๋ค.
์ด๋ ์ฝ๋์ด๋ ์ปดํฌ๋ํธ ๊ฐ์ ๊ฒฐํฉ๋๋ฅผ ๋ฎ์ถ๋ ๊ฒ์ ๋งค์ฐ ์ค์ํ๋ค๊ณ ์๊ฐํ๋ฉฐ, Props์ Emits๋ Vue์ ํต์ฌ์ ์ธ ๋ฐ์ดํฐ ํ๋ฆ ๊ด๋ฆฌ ๋๊ตฌ๋ก์จ, ๋จ๋ฐฉํฅ ๋ฐ์ดํฐ ํ๋ฆ๊ณผ ์ด๋ฒคํธ ๊ธฐ๋ฐ ํต์ ์ ํตํด ์ปดํฌ๋ํธ ๊ฐ ๊ฒฐํฉ๋๋ฅผ ์ต์ํ ํ ์ ์๋๋ก ํด์ฃผ๋ ์ฃผ์ ๊ธฐ๋ฅ์ ๋๋ค. Props๋ก ๋ถ๋ชจ์์ ์์์ผ๋ก ๋ฐ์ดํฐ๋ฅผ ์ ๋ฌํ๊ณ , Emits๋ก ์์์์ ๋ถ๋ชจ๋ก ์ด๋ฒคํธ๋ฅผ ์ ๋ฌํจ์ผ๋ก์จ ์ปดํฌ๋ํธ ๊ฐ์ ๋ฐ์ดํฐ๋ฅผ ํจ์จ์ ์ผ๋ก ๊ตํํ ์ ์์ผ๋, ์ ์ฉํ๊ฒ ์ฌ์ฉํ์๊ธธ ๋ฐ๋๋๋ค.