[Vue.js] Computed Properties

1. 왜 씀?

Computed Properties는 왜 필요할까?

const author = reactive({
  name: 'John Doe',
  books: [
    'Vue 2 - Advanced Guide',
    'Vue 3 - Basic Guide',
    'Vue 4 - The Mystery'
  ]
})
Code language: JavaScript (javascript)
<p>책을 가지고 있다:</p>
<span>{{ author.books.length > 0 ? 'Yes' : 'No' }}</span>
Code language: HTML, XML (xml)

템플릿 내 표현식은 유지보수에 불리하다.

<span>{{ author.books.length > 0 ? 'Yes' : 'No' }}</span>
<span>{{ author.books.length > 0 ? 'Yes' : 'No' }}</span>
<span>{{ author.books.length > 0 ? 'Yes' : 'No' }}</span>
<span>{{ author.books.length > 0 ? 'Yes' : 'No' }}</span>
<span>{{ author.books.length > 0 ? 'Yes' : 'No' }}</span>
...
Code language: HTML, XML (xml)

템플릿의 여러 곳에서 사용되면 같은 표현식이 여러 번 사용된다.

이는 일관성 있게 관리하기 어렵다.

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

const author = reactive({
  name: 'John Doe',
  books: [
    'Vue 2 - Advanced Guide',
    'Vue 3 - Basic Guide',
    'Vue 4 - The Mystery'
  ]
})

// 계산된 ref
const publishedBooksMessage = computed(() => {
  return author.books.length > 0 ? 'Yes' : 'No'
})
</script>

<template>
  <p>책을 가지고 있다:</p>
  <span>{{ publishedBooksMessage }}</span>
</template> 
Code language: HTML, XML (xml)

publishedBooksMessage라는 computed property가 선언되었다.

computed() 함수에는 getter로 사용될 function이 입력돼야 하며, 반환되는 값은 computed ref다.

마찬가지로 계산 결과를 publishedBooksMessage.value로 접근할 수 있다.

computed property은 의존된 반응형을 자동으로 추적한다.

publishedBooksMessageauthor.books에 의존하고 있고, author.books가 변경되면 publishedBooksMessage을 포함한 의존하는 모든 것을 업데이트한다.

💡 주의점 getter에서 발생할 수 있는 사이드 이펙트를 방지하기 위해서 getter는 순수함수여야 한다.


2. 아니 Method로 하면 되잖아요!

<p>{{ calculateBooksMessage() }}</p>
Code language: HTML, XML (xml)
// in component
function calculateBooksMessage() {
  return author.books.length > 0 ? 'Yes' : 'No'
}
Code language: JavaScript (javascript)

눈에 보이는 결과는 같다.

하지만 computed property는 reactive dependencies 기반으로 캐싱된다!

reactive dependencies(author.books)가 변경되지 않았다면 여러 곳에서 computed property(publishedBooksMessage)에 접근할 경우, getter 함수를 다시 실행하지 않고 이전에 계산된 결과를 재사용한다.

캐싱을 원하지 않는 경우에만 메서드 호출을 사용하자.


3. Writable Computed

필요하다면 getter와 setter를 모두 제공하여 수정 가능한 computed property를 선언할 수 있다.

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

const firstName = ref('John')
const lastName = ref('Doe')

const fullName = computed({
  // getter
  get() {
    return firstName.value + ' ' + lastName.value
  },
  // setter
  set(newValue) {
    // Note: we are using destructuring assignment syntax here.
    [firstName.value, lastName.value] = newValue.split(' ')
  }
})
</script>
Code language: HTML, XML (xml)

이제 fullName.value = 'John Doe'를 실행하면 setter가 호출되고, 그에 따라 firstNamelastName이 업데이트된다.

하.지.만 되도록 computed property는 읽기 전용으로 사용하자.


댓글 남기기