조아마시

쓸모 있는 상세페이지 만들기

웹개발/vuejs

[Vue] Vue 3에서 계산된 속성(computed) 사용하기

joamashi 2024. 7. 29. 00:03

Vue 3의 computed는 데이터 속성에 의존하는 값을 계산하고 캐싱하는 데 사용되는 강력한 도구입니다. 템플릿에서 간결하게 표현식을 사용하여 값을 참조할 수 있도록 하며, 데이터 변경에 대한 반응성도 제공합니다.

<template>
  <div>
    이름: {{ fullName }} 나이: {{ age }}
  </div>
</template>

<script>
export default {
  setup() {
    const firstName = '김';
    const lastName = '철수';
    const age = 30;

    // getter 함수를 사용하여 계산된 속성 정의
    const fullName = computed(() => {
      return `${firstName} ${lastName}`;
    });

    return {
      fullName,
      age
    };
  }
}
</script>

위 코드에서 fullName은 firstName과 lastName 속성에 의존하는 계산된 속성입니다. 템플릿에서 {{ fullName }}으로 간단하게 참조할 수 있으며, firstName 또는 lastName 값이 변경될 때마다 자동으로 다시 계산됩니다.

주요 특징:

  • 캐싱: 계산된 속성은 의존하는 데이터가 변경되지 않는 한 다시 계산되지 않습니다. 이는 성능 향상에 도움이 됩니다.
  • 반응성: 의존하는 데이터가 변경되면 자동으로 다시 계산되어 템플릿 갱신을 트리거합니다.
  • 메서드와 차이점: computed는 값을 반환하는 함수이지만, methods는 작업을 수행하는 함수입니다. 템플릿에서 직접 값을 참조해야 하는 경우 computed를 사용하고, 작업을 수행해야 하는 경우 methods를 사용합니다.

고급 사용법:

  • setter 사용: 읽기 전용이 기본이지만, setter를 사용하여 계산된 속성 값을 변경할 수 있습니다. 주의해서 사용해야 하며, 의도하지 않은 부작용을 유발할 수 있으므로 주의가 필요합니다.
  • watch 사용: 계산된 속성 내에서 다른 데이터 속성의 변화를 감시하고 싶을 때 watch를 사용할 수 있습니다.
  • 컴포넌트 간 계산된 속성 공유: provide/inject API를 사용하여 계산된 속성을 다른 컴포넌트에서 사용할 수 있습니다.

Vue 3 computed 다양한 예제

1. 기본 예제:

이전 예시에서 살펴본 기본적인 사용법입니다. firstNamelastName 속성을 사용하여 fullName이라는 계산된 속성을 만들고, 템플릿에서 간단하게 표현식으로 참조합니다.

<template>
  <div>
    이름: {{ fullName }} 나이: {{ age }}
  </div>
</template>

<script>
export default {
  setup() {
    const firstName = '김';
    const lastName = '철수';
    const age = 30;

    const fullName = computed(() => {
      return `${firstName} ${lastName}`;
    });

    return {
      fullName,
      age
    };
  }
}
</script>

2. 포맷팅된 값 표시:

숫자, 날짜, 시간 등을 원하는 형식으로 표시하고 싶을 때 활용할 수 있습니다.

<template>
  <div>
    가격: {{ price | currency }} 원, 날짜: {{ date | formatDate }}
  </div>
</template>

<script>
import { ref, computed } from 'vue';
import { useFilters } from './filters'; // 커스텀 필터 정의된 곳

export default {
  setup() {
    const price = ref(10000);
    const date = ref(new Date());

    const formattedPrice = computed(() => {
      return price.value | currency; // 커스텀 필터 사용
    });

    const formattedDate = computed(() => {
      return date.value | formatDate; // 커스텀 필터 사용
    });

    return {
      price,
      date,
      formattedPrice,
      formattedDate
    };
  }
}
</script>

3. 조건부 계산:

템플릿에 표시되는 값을 특정 조건에 따라 다르게 계산하고 싶을 때 활용할 수 있습니다.

<template>
  <div>
    {{ message }}
  </div>
</template>

<script>
export default {
  setup() {
    const isAdult = ref(false);
    const message = computed(() => {
      return isAdult.value ? '성인입니다.' : '미성년자입니다.';
    });

    return {
      isAdult,
      message
    };
  }
}
</script>

4. 배열 및 객체 계산:

배열이나 객체의 값을 기반으로 새로운 데이터를 계산하거나 변형할 때 활용할 수 있습니다.

<template>
  <div>
    <ul>
      <li v-for="item in items" :key="item.id">
        {{ item.name }} - {{ itemPrice(item) }}원
      </li>
    </ul>
  </div>
</template>

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

export default {
  setup() {
    const items = ref([
      { id: 1, name: '사과', price: 1000 },
      { id: 2, name: '바나나', price: 500 },
      { id: 3, name: '포도', price: 2000 },
    ]);

    const itemPrice = computed((item) => {
      return item.price * (isSale ? 0.9 : 1); // 할인 적용 여부에 따라 가격 계산
    });

    const isSale = ref(false);

    return {
      items,
      isSale,
      itemPrice
    };
  }
}
</script>

5. watch 사용:

computed 속성 내에서 다른 데이터 속성의 변화를 감시하고 싶을 때 watch를 사용할 수 있습니다. 이는 computed 자체가 값을 계산하는 역할만 하고, 변화 감지를 위한 별도의 로직이 필요할 경우 유용합니다.

예제:

<template>
  <div>
    수: {{ count }} - {{ evenOrOdd }}
    <button @click="count++">증가</button>
  </div>
</template>

<script>
export default {
  setup() {
    const count = ref(0);

    const evenOrOdd = computed(() => {
      return count.value % 2 === 0 ? '짝수' : '홀수';
    });

    // watch를 사용하여 count 변화 감시 및 evenOrOdd 업데이트
    watch(count, (newValue, oldValue) => {
      console.log(`count 변화: ${oldValue} -> ${newValue}`);
      // 여기서 evenOrOdd를 직접 업데이트하는 로직 작성 가능
    });

    return {
      count,
      evenOrOdd
    };
  }
}
</script>

watch 옵션:

  • handler: 값 변화 감지 시 실행되는 함수입니다.
  • immediate: true로 설정하면 컴포넌트 생성 시 즉시 한 번 실행됩니다.
  • deep: true로 설정하면 객체 또는 배열의 하위 값 변화도 감지합니다.

주의 사항:

  • watch는 성능에 영향을 줄 수 있으므로, 필요한 경우에만 사용하는 것이 좋습니다.
  • 계산된 속성 값 자체를 변경해야 하는 경우 setter를 사용하는 것이 더 적합합니다.

computed vs watch:

  • 사용 시점:
    • computed: 값을 계산하고 템플릿에서 사용할 때
    • watch: 다른 데이터 속성 변화에 반응하여 작업을 수행할 때
  • 성능:
    • computed: 캐싱되어 반응성이 높음
    • watch: 성능 영향 가능성이 있음
  • 사용 예시:
    • computed: 포맷팅, 조건부 계산, 배열/객체 기반 계산
    • watch: API 호출, 로컬 스토리지 업데이트, 로그 출력

참고 자료:

  • Vue 3 공식 문서 - watch API [유효하지 않은 URL 삭제됨]
  • Vue 3 computed와 watch 옵션 - velog [유효하지 않은 URL 삭제됨]

watchcomputed와 함께 사용하여 데이터 변화에 효과적으로 반응하고 필요한 작업을 수행하는 강력한 도구입니다.

728x90