Props
단방향 데이터 흐름
부모 → 자식 방향으로 데이터 전달
부모 컴포넌트가 업데이트될 때마다 자식 컴포넌트의 모든 props가 최신 값으로 업데이트된다.
따라서 자식 컴포넌트 내부에서 props를 변경하려 하면 안된다.
defineProps
<script setup> 스타일의 SFC에서는 defineProps() 매크로를 사용하여 props 선언 가능
<script setup>
import { ref } from 'vue'
import ChildComp from './ChildComp.vue'
const greeting = ref('Hello from parent')
const props = defineProps({
msg: String
})
</script>
<template>
<ChildComp :msg="greeting"/>
</template>
자식 컴포넌트에서 props를 변경해야 하는 경우
1. props는 초기 값을 전달하는 데만 사용하고, 이를 자식 컴포넌트에서 로컬 데이터 속성으로 할당하여 사용
const props = defineProps(['initialCounter'])
// props.initialCounter는 counter의 초기 값으로 사용됩니다.
// 추후 props가 갱신되어도 counter 값이 업데이트 되지 않습니다.
const counter = ref(props.initialCounter)
2. prop 값을 사용하여 계산된 속성 정의
const props = defineProps(['size'])
// prop이 변경될 때, 계산된 속성은 자동으로 업데이트 됩니다.
const normalizedSize = computed(() => props.size.trim().toLowerCase())
😑 computed의 get, set과 props, emit을 사용할 경우 하위 컴포넌트 요소의 v-model에 props로 받은 데이터를 바인딩해야 하면서도 상위 컴포넌트에 선언된 원 데이터를 바꿔주는 것이 가능하다.
그냥 v-model 쓰면 되지, 누가 이런 바보같은 방식을 써? 라고 생각했지만... 써야만 하는 상황이 있었다.
Emit
자식 → 부모로 특정한 이벤트 전달
defineEmits
emit 옵션을 사용하기 위해 선언하는 Vue 내장 APIs로, 하위 컴포넌트에서 상위 컴포넌트로 이벤트를 전달할 때 명시하고 사용한다.
첫 번째 인자 : 이벤트 이름
<script setup>
import { ref } from 'vue'
import ChildComp from './ChildComp.vue'
const childMsg = ref('No child msg yet')
const emit = defineEmits(['response'])
emit('response', 'hello from child')
</script>
<template>
<ChildComp @response="(msg) => childMsg = msg"/>
<p>{{ childMsg }}</p>
</template>
example 1
// 자식컴포넌트
const emit = defineEmits = ['toggle-todo'];
const toggleTodo = (index) => {
emit('toggle-todo', index);
}
// index라는 값을 toggle-todo 라는 이름으로 보냄( 자식 -> 부모 )
// 부모컴포넌트
<todoList @toggle-todo="toggleTodo"/>
const toggleTodo = (index) => {
todos.value[index].completed = true
}
// 아까 자식컴포넌트에서 보낸 index의 값이 여기 위의 인자 index에 들어오는 것임
example 2
// button.vue 하위컴포넌트
<template>
<button @click="$emit('test-emit')"> Emit 버튼 </button>
</template>
<script setup>
defineEmits(["test-emit"]);
</script>
// index.vue 상위컴포넌트
<template>
<button @test-emit="checkEmit"/>
</template>
<script setup>
import button from '@/component/button.vue'
const checkEmit = () => {
console.log('emit 발생')
}
</script>
[ 참고 자료 ]
https://ko.vuejs.org/guide/components/props.html
https://ko.vuejs.org/guide/components/events.html
'Vue' 카테고리의 다른 글
[ Vue ] defineProps에 타입을 지정하는 2가지 방법 (0) | 2024.03.27 |
---|---|
[ Vue ] 의존성 주입 (Provide Injection) (0) | 2024.03.27 |
[ Vue ] v-slot이란? | v-slot으로 공통 컴포넌트 만들기 (0) | 2024.03.27 |
[ Vue ] v-html 사용을 지양해야 하는 이유 (0) | 2024.03.27 |
[ Vue ] 버전 업그레이드 (3.0 → 3.3) (0) | 2024.03.27 |