dev.syw

파생 상태와 부수 효과를 다루는 computed·watch·watchEffect.

computed 와 watch

화면에는 원본 데이터를 그대로 쓰기보다, 그걸 가공한 파생 값이 필요한 경우가 많습니다. "장바구니 총합", "검색 필터링 결과" 같은 것들이죠. 또 데이터가 바뀔 때 API 호출이나 로깅 같은 부수 효과를 실행하고 싶을 때도 있습니다. 전자는 computed, 후자는 watch 가 담당합니다.

학습 목표

  • computed 로 파생 값을 만들고 캐싱 이점을 이해한다.
  • computed 와 메서드의 차이를 안다.
  • watch 로 특정 값의 변화에 반응한다.
  • watchEffect·즉시 실행(immediate)·깊은 감시(deep)를 활용한다.

computed — 파생 상태

computed 는 다른 반응형 값으로부터 계산된 값을 만듭니다. 의존하는 값이 바뀔 때만 다시 계산하고, 그렇지 않으면 캐시된 결과를 돌려줍니다.

<script setup>
import { ref, computed } from 'vue';

const price = ref(1000);
const qty = ref(3);

const total = computed(() => price.value * qty.value);
</script>

<template>
  <p>총합: {{ total }}원</p>
</template>

priceqty 가 바뀌면 total 이 자동으로 다시 계산됩니다.

computed vs 메서드

같은 결과를 메서드로도 만들 수 있지만, 동작이 다릅니다.

const totalMethod = () => price.value * qty.value;  // 호출할 때마다 매번 계산
const total = computed(() => price.value * qty.value); // 의존값 안 바뀌면 캐시
JavaScript
구분computed메서드
캐싱O (의존값 변화 시만 재계산)X (호출 시 매번 실행)
호출{{ total }}{{ totalMethod() }}

💡 TIP — 화면에 여러 번 쓰이는 파생 값이나 무거운 계산이라면 computed 가 성능상 유리합니다.

watch — 값 변화 감시

watch 는 특정 반응형 값을 지켜보다가, 바뀌면 콜백을 실행합니다. 새 값과 이전 값을 모두 받을 수 있습니다.

<script setup>
import { ref, watch } from 'vue';

const keyword = ref('');

watch(keyword, (newVal, oldVal) => {
  console.log(`검색어: ${oldVal}${newVal}`);
  // 여기서 API 호출 등 부수 효과 실행
});
</script>

여러 소스를 한 번에 감시하려면 배열로 넘깁니다.

watch([price, qty], ([newPrice, newQty]) => {
  console.log(newPrice, newQty);
});
JavaScript

watchEffect — 의존성 자동 추적

watchEffect 는 감시 대상을 따로 지정하지 않습니다. 콜백 안에서 사용한 반응형 값을 자동으로 추적하고, 그중 하나라도 바뀌면 다시 실행합니다.

import { watchEffect } from 'vue';

watchEffect(() => {
  console.log(`현재 검색어: ${keyword.value}`); // keyword 를 자동 감지
});
JavaScript

watch 는 "무엇을 감시할지 명시", watchEffect 는 "콜백 내부에서 자동 감지"라는 차이가 있습니다.

즉시 실행과 깊은 감시

watch 는 기본적으로 값이 바뀔 때부터 동작합니다. 처음에 한 번 바로 실행하려면 immediate, 객체 내부 깊은 변경까지 감지하려면 deep 옵션을 줍니다.

watch(
  user,
  (val) => console.log('user 변경', val),
  { immediate: true, deep: true }
);
JavaScript

⚠️ 주의deep 은 객체 전체를 재귀 탐색하므로 큰 객체에선 비용이 큽니다. 꼭 필요한 속성만 감시하도록 () => user.value.name 처럼 getter 함수로 좁히는 게 좋습니다.

요약

  • computed 는 의존값이 바뀔 때만 재계산하는 캐시된 파생 값이다.
  • 같은 계산이라도 메서드는 매번 실행, computed 는 캐싱된다.
  • watch 는 명시한 값의 변화에 반응하고 새/이전 값을 받는다.
  • watchEffect 는 의존성을 자동 추적하며, immediate·deep 옵션으로 동작을 조절한다.

연습문제

  1. firstName, lastName 두 ref를 합쳐 fullNamecomputed 로 만들어 보세요.
  2. 1번을 메서드로도 만들고, 화면에서 호출 방식 차이를 설명해 보세요.
  3. count 가 바뀔 때마다 콘솔에 이전 값과 새 값을 찍는 watch 를 작성해 보세요.
  4. watchEffectcount 를 추적해, 컴포넌트가 처음 그려질 때도 한 번 실행되는지 확인해 보세요.

힌트computed(() => first.value + ' ' + last.value). watchEffect 는 별도 옵션 없이도 처음에 한 번 즉시 실행됩니다.

💡 연습문제 풀이

불러오는 중…

함께 보면 좋은 자료

댓글 0

Vue.js” 강좌에 대한 댓글입니다.

댓글을 작성하려면 로그인이 필요합니다.