Vue2에서도 익숙하게 사용하던 computed와 watch. Vue3에서는 Composition API 방식으로 이들을 더 유연하게 사용할 수 있습니다. 이번 글에서는 Vue3에서 computed()와 watch()를 어떻게 사용하는지, 그리고 각각의 차이점은 무엇인지 정리해봅니다.
1. computed()란?
computed()는 계산된 값을 반환하는 반응형 함수입니다. 의존하는 값이 변경될 때만 자동으로 재계산되며, 캐싱되는 특징이 있어 성능상 유리합니다.
예제: computed() 기본 사용법
import { ref, computed } from 'vue'
export default {
setup() {
const price = ref(100)
const quantity = ref(2)
const total = computed(() => price.value * quantity.value)
return {
price,
quantity,
total
}
}
설명:
- total은 price 또는 quantity가 변경될 때만 다시 계산됩니다.
- 템플릿에서는 .value 없이 {{ total }}로 사용 가능.
2. watch()란?
watch()는 값의 변화를 감지하여 특정 로직을 실행하는 함수입니다. 비동기 작업(API 호출 등)이나 사이드 이펙트 처리 시 유용합니다.
예제: watch() 기본 사용법
import { ref, watch } from 'vue'
export default {
setup() {
const name = ref('Vue')
watch(name, (newVal, oldVal) => {
console.log(`name changed from ${oldVal} to ${newVal}`)
})
return { name }
}
}
설명
- name이 변경될 때마다 콜백이 실행됩니다.
- 이전 값과 새로운 값을 모두 받을 수 있음.
3. watch vs computed 차이점
구분 | computed() | watch() |
용도 | 값을 계산하고 반환 변화 | 감지 후 특정 작업 실행 |
반환 값 | 있음 (return 필수) | 없음 (로직만 실행) |
의존성 | 내부에서 자동으로 추적 | 감시 대상 명시 필요 |
캐싱 여부 | 캐싱됨 | 매번 실행됨 |
사용 예시 | 합계, 필터링 결과, 조건부 값 등 | API 호출, localStorage 저장, 로그 출력 등 |
4. watch 사용 시 옵션
watch()는 세부 설정을 위한 옵션도 제공합니다.
예시: immediate, deep
watch(
name,
(newVal) => {
console.log('changed:', newVal)
},
{
immediate: true, // 최초 실행 시 한 번 실행됨
deep: true // 객체 내부까지 감시 (reactive 객체일 때)
}
)
5. 배열, 객체 감시하기
- ref()로 감싼 배열 → .value 사용
- reactive() 객체 감시 → () => state.xxx 또는 deep: true 옵션
const list = ref([1, 2, 3])
watch(list, (newVal) => {
console.log('list changed:', newVal)
})
const state = reactive({ user: { name: '홍길동' } })
watch(() => state.user, (newVal) => {
console.log('user changed:', newVal)
}, { deep: true })
마무리 요약
목적 | 사용할 것 |
계산된 값 반환 | computed() |
값의 변화 감지 및 반응 | watch() |
반응형 캐싱이 필요할 때 | computed() |
외부 API 호출 또는 로그 등 실행할 때 | watch() |
Vue3에서는 computed()와 watch()를 통해 상태 관리와 반응형 처리에 더 세밀하게 접근할 수 있습니다. Composition API로 바뀌면서 코드의 가독성과 모듈화도 좋아진듯 합니다.