
-> "공통된 부모 컴포넌트에서 관리하자"

부모는 자식에게 데이터를 전달(Pass Props)하며,
자식은 자신에게 일어난 일을 부모에게 알림(Emit event)
부모 컴포넌트로부터 자식 컴포넌트로 데이터를 전달하는 데 사용되는 속성
-> 부모 컴포넌트에서만 변경하고 이를 내려 받는 자식 컴포넌트는 자연스럽게 갱신
모든 props는 자식 속성과 부모 속성 사이에
하향식 단방향 바인딩을 형성
(one-way-down binding)
-> 데이터 흐름의 "일관성" 및 "단순화"
// main.js
import './assets/main.css'
<!-- App.vue -->
<template>
<div>
<Parent />
</div>
</template>
<script setup>
import Parent from '@/components/Parent.vue'
</script>
<!-- Parent.vue -->
<template>
<div>
<ParentChild />
</div>
</template>
<script setup>
import ParentChild from '@/components/ParentChild.vue'
</script>
<!-- ParentChild.vue -->
<template>
<div></div>
</template>
<script setup>
</script>
부모 컴포넌트에서 내려 보낸 props를 사용하기 위해서는
자식 컴포넌트에서 명시적인 props 선언이 필요
<template>
<div>
<ParentChild my-msg="message" />
</div>
</template>
<script setup>
defineProps()
</script>
<!-- ParentChild.vue -->
<script setup>
defineProps(['myMsg'])
</script>
※ 객체 선언 문법 사용 권장
<!-- ParentChild.vue -->
<script setup>
defineProps({
'myMsg': String
})
</script>
<!-- ParentChild.vue -->
<div>
<p>{{ myMsg }}</P>
</div>
<script setup>
const props = defineProps({ myMsg: String })
console.log(props) // {myMsg: 'message'}
console.log(props.myMsg) // 'message'
</script>
<!-- ParentGrandChild.vue -->
<template>
<div>
</div>
</template>
<script setup>
</script>
<!-- ParentChild.vue -->
<template>
<div>
<p>{{ myMsg }}</p>
<ParentGrandChild />
</div>
</template>
<script setup>
import ParentGrandChild from '@/components/ParentGrandChild.vue'
defineProps({
myMsg: String,
})
</script>
<!-- ParentChild.vue -->
<template>
<div>
<p>{{ myMsg }}</p>
<ParentGrandChild :my-msg="myMsg" />
</div>
</template>
<!-- ParentGrandChild.vue -->
<template>
<div>
<p>{{ myMsg }}</p>
</div>
</template>
<script setup>
defineProps({
myMsg: String
})
</script>
<ParentChild my-msg="message" />
defineProps({
myMsg: String
})
<p>{{ myMsg }}</p>
// Parent.vue
import { ref } from 'vue'
const name = ref('Alice')
<!-- Parent.vue -->
<ParentChild my-msg="message" :dynamic-props="name" />
// ParentChild.vue
defineProps({
myMsg: String,
dynamicProps: String,
})
<!-- ParentChild.vue -->
<p>{{ dynamicProps }}</p>
v-for와 함께 사용하여 반복되는 요소를 props로 전달하기
ParentItem 컴포넌트 생성 및 Parent의 하위 컴포넌트로 등록
<!-- ParentItem.vue -->
<template>
<div>
</div>
</template>
<script setup>
</script>
<!-- Parent.vue -->
<template>
<div>
<ParentItem />
</div>
</template>
<script setup>
import ParentItem from '@/components/ParentItem.vue'
</script>
// Parent.vue
const items = ref([
{ id: 1, name: '사과' },
{ id: 2, name: '바나나' },
{ id: 3, name: '딸기' }
])
<!-- Parent.vue -->
<ParentItem
v-for="item in items"
:key="item.id"
:my-prop="item"
/>
<template>
<div>
<p>{{ myProp.id }}</p>
<p>{{ myProp.name }}</p>
</div>
</template>
<script setup>
defineProps({
myProp: Object
})
</script>


부모는 자식에게 데이터를 전달(Pass Props)하며,
자식은 자신에게 일어난 일을 부모에게 알림(Emit event)
-> 부모가 props 데이터를 변경하도록 소리쳐야 한다.
자식 컴포넌트가 이벤트를 발생시켜 부모 컴포넌트로 데이터를 전달하는 역할의 메서드
※ '$'표기는 Vue 인스턴스의 내부 변수들을 가리킴
※ Life cycle hooks, 인스턴스 메서드 등 내부 특정 속성에 접글할 때 사용
$emit(event, ...args)
<button @click="$emit('soneEvent')">클릭</button>
<ParentComp @some-event="someCallback" />
<!-- ParentChild.vue -->
<button @click="$emit('someEvent')">클릭</button>
<!-- Parent.vue -->
<ParentChild
@some-event="someCallback"
my-msg="message"
:dynamic-props="name"
/>
// Parent.vue
const someCallback = function () {
console.log('ParentChild가 발신한 이벤트를 수신했다!')
}

<script setup>
defineEmits()
</script>
<script setup>
const emit = defineEmits(['someEvent', 'myFocus'])
const buttonClick = function () {
emit('someEvent')
}
</script>
<!-- ParentChild.vue -->
<template>
<button @click="buttonClick">클릭</button>
</template>
<script setup>
const emit = defineEmits(['someEvent'])
const buttonClick = function () {
emit('someEvent')
}
</script>
<!-- ParentChild.vue -->
<template>
<button @click="emitArgs">추가 인자 전달</button>
</template>
<script setup>
const emit = defineEmits(['someEvent', 'emitArgs'])
const buttonClick = function () {
emit('emitArgs', 1, 2, 3)
}
</script>
<!-- Parent.vue -->
<template>
<ParentChild
@some-event="someCallback"
@emit-args="getNumbers"
my-msg="message"
:dynamic-props="name"
/>
</template>
<script setup>
const getNumbers = function (...args) {
console.log(args)
console.log(`ParentChild가 전달한 추가인자 ${args}를 수신했어요.`)
}
</script>

<button @click="$emit('someEvent')">버튼1</button>
const emit = defineEmits(['someEvent'])
emit('someEvent')
<ParentChild @someEvent='...' />