[ Vue ] computed

Danbi Cho·2021년 3월 21일
1

Vue

목록 보기
3/3

vue.js에서 computed 프로퍼티는 유용하게 사용된다.
하지만 프로젝트를 하게 됐을 때 computed와 watch 두 가지를 다 사용하고 있었는데, computed / watch 모두 반응형이라는 키워드와 관련이 있다고만 이해하고 있었고 정확한 차이점을 잘 알지 못하고 사용했다.

computed

computed는 "반응형 getter"라고 할 수 있다.

<div id="example">
  <p>원본 메시지: "{{ message }}"</p>
  <p>역순으로 표시한 메시지: "{{ reversedMessage }}"</p>
</div>

var vm = new Vue({
  el: '#example',
  data: {
    message: '안녕하세요'
  },
  computed: {
    // 계산된 getter
    reversedMessage: function () {
      // `this` 는 vm 인스턴스를 가리킵니다.
      return this.message.split('').reverse().join('')
    }
  }
})

위 코드의 결과는 아래와 같다.

원본 메시지: "안녕하세요"
역순으로 표시한 메시지: "요세하녕안"
  • computed 프로퍼티를 보면 reversedMessage를 선언하고 그 값으로 아래 처럼 익명함수가 할당되어있다.
  • computed에 정의하는 익명함수는 반드시 값을 리턴해야 한다.

getter

console.log(vm.reversedMessage) // => '요세하녕안'
vm.message = 'Goodbye'
console.log(vm.reversedMessage) // => 'eybdooG'
  • computed의 reversedMessage를 프로퍼티가 정의될 때 내부적으로 Object.defineProperty를 통해 정의 되고, 이 때 익명함수가 getter로 설정된다.

  • vm.reversedMessage의 값은 항상 vm.message의 값에 의존한 상태이다.

  • 일반 속성처럼 computed에도 템플릿에서 데이터 바인딩을 할 수 있다. Vue는 vm.reversedMessage가 vm.message의 값의 변화를 보고 있다는 것을 알기 때문에 vm.message가 바뀔 때 vm.reversedMessage에 의존하는 바인딩을 모두 업데이트한다.

computed 속성의 캐싱 vs 메소드

<p>뒤집힌 메시지: "{{ reversedMessage() }}"</p>

// 컴포넌트 내부
methods: {
  reversedMessage: function () {
    return this.message.split('').reverse().join('')
  }
}
  • computed 프로퍼티 대신 메소드와 같은 함수를 정의할 수도 있다. 결과적으로 computed와 메소드의 결과는 같지만, computed 프로퍼티는 종속 대상을 따라 저장(캐싱)된다는 것이다.

  • computed는 속성이 종속된 대상의 값이 바뀔 때만 함수를 실행하고, 즉 message가 바뀌지 않으면 reversedMessage를 여러번 요청해도 계산하지 않고 이전에 계산되어 있던 결과를 반환한다.

  • 이에 비해 메소드를 호출하면 렌더링을 다시 할 때마다 항상 함수를 실행한다.

  • 이러한 특성이 생기게 된 것은 getter의 특성이라고 할 수 있다. (이 특성 때문에 메소드와 차이가 생기기도 한다.) 이 점 때문에 값이 변해도 캐싱때문에 변경된 값을 인지하지 못하는 단점이 생기기도 한다.

🤔 여기서 캐싱은 왜 필요할까?
만약 계산에 시간에 오래 걸리는 computed 프로퍼티인 A를 가지고 있다면, 이 속성을 계산하기 위해 많은 데이터와 계산을 해야한다. 그런데 A에 의존하는 다른 computed 속성값도 있을 수 있는데, 캐싱을 하지 않으면 A의 getter 함수를 필요 이상으로 더 실행하게 된다. 그래서 캐싱을 원하지 않는 경우 메소드를 사용하는 것이 효율적이다.

profile
룰루랄라! 개발자 되고 싶어요🙈

0개의 댓글