Contents
see ListVue 3 Composition API 활용법
Vue 3의 Composition API를 사용하면 로직을 재사용 가능한 함수로 구성하고 더 유연한 컴포넌트를 작성할 수 있습니다.
Options API vs Composition API
// Options API (Vue 2 스타일)
export default {
data() { return { count: 0 } },
methods: { increment() { this.count++ } },
computed: { double() { return this.count * 2 } }
}
// Composition API (Vue 3)
import { ref, computed } from \047vue\047
export default {
setup() {
const count = ref(0)
const increment = () => count.value++
const double = computed(() => count.value * 2)
return { count, increment, double }
}
}script setup (권장)
<script setup>
import { ref, computed, onMounted } from \047vue\047
// 반응형 상태
const count = ref(0)
const user = ref({ name: \047홍길동\047 })
// 계산된 속성
const double = computed(() => count.value * 2)
// 메서드
const increment = () => count.value++
// 라이프사이클
onMounted(() => {
console.log(\047컴포넌트 마운트됨\047)
})
</script>
<template>
<button @click="increment">{{ count }}</button>
<p>Double: {{ double }}</p>
</template>ref vs reactive
import { ref, reactive } from \047vue\047
// ref: 원시값, 개별 값
const count = ref(0)
count.value++ // .value 필요
// reactive: 객체
const state = reactive({
count: 0,
user: { name: \047Kim\047 }
})
state.count++ // .value 불필요
// toRefs: reactive를 ref로 분해
const { count: countRef } = toRefs(state)Composables (로직 재사용)
// composables/useMouse.js
import { ref, onMounted, onUnmounted } from \047vue\047
export function useMouse() {
const x = ref(0)
const y = ref(0)
const update = (e) => {
x.value = e.pageX
y.value = e.pageY
}
onMounted(() => window.addEventListener(\047mousemove\047, update))
onUnmounted(() => window.removeEventListener(\047mousemove\047, update))
return { x, y }
}
// 컴포넌트에서 사용
<script setup>
import { useMouse } from \047./composables/useMouse\047
const { x, y } = useMouse()
</script>watch와 watchEffect
import { ref, watch, watchEffect } from \047vue\047
const count = ref(0)
const name = ref(\047\047)
// watch: 명시적 의존성
watch(count, (newVal, oldVal) => {
console.log(\047count changed:\047, newVal)
})
// 여러 소스 감시
watch([count, name], ([newCount, newName]) => {
console.log(newCount, newName)
})
// 깊은 감시
watch(user, (newVal) => {}, { deep: true })
// 즉시 실행
watch(count, handler, { immediate: true })
// watchEffect: 자동 의존성 추적
watchEffect(() => {
console.log(\047count is:\047, count.value)
})라이프사이클 훅
import {
onBeforeMount,
onMounted,
onBeforeUpdate,
onUpdated,
onBeforeUnmount,
onUnmounted
} from \047vue\047
onMounted(() => {
console.log(\047DOM 준비됨\047)
})
onUnmounted(() => {
console.log(\047정리 작업\047)
})Props와 Emits
<script setup>
// Props 정의
const props = defineProps({
title: String,
count: { type: Number, default: 0 }
})
// TypeScript
const props = defineProps<{
title: string
count?: number
}>()
// Emits 정의
const emit = defineEmits([\047update\047, \047delete\047])
emit(\047update\047, newValue)
</script>provide/inject
// 부모 컴포넌트
import { provide, ref } from \047vue\047
const theme = ref(\047dark\047)
provide(\047theme\047, theme)
// 자식 컴포넌트 (깊이 무관)
import { inject } from \047vue\047
const theme = inject(\047theme\047, \047light\047) // 기본값