본문 바로가기
VueJS/VueJS

[VueJS] computed와 watch 속성 비교

by 썸머워즈 2021. 9. 7.
반응형

vueJS에서 제공하는 computed와 watch 속성에 대해 알아보자.

 

왜 이 두가지를 동시에 다루냐면 서로 비슷한 특징을 가지고 있기도 하고,

처음 접할때도 둘을 비교하는 경우가 많았기 때문에 나 역시 같이 기록해두고자 한다.

 

역시 vueJS는 공식홈페이지가 너무 잘되어있기 때문에 예제를 그대로 가져와 사용해보고자 한다.


1. computed

<div id="example">
  <p>원본 메시지: "{{ message }}"</p>
  <p>역순으로 표시한 메시지: "{{ reversedMessage }}"</p>
</div>
var vm = new Vue({
  el: '#example',
  data: {
    message: '안녕하세요'
  },
  computed: {
    reversedMessage: function () {
      return this.message.split('').reverse().join('')
    }
  }
})

 

▷ 결과

원본 메시지: "안녕하세요"
역순으로 표시한 메시지: "요세하녕안"

 

이렇게 본다면 당연히 methods와의 차이점을 느낄수가 없는데,

나 역시 도대체 computed는 methods와 기능이 동일한데 왜 존재하며 왜 사용하는걸까? 라는 의문을 가졌었다.

 

computed와 methods의 차이점을 보며 computed의 특징을 알아보도록하자.

 

위 예제를 보면 computed에 reversedMessage를 선언해 놨는데, reversedMessage는 message에 의존하는 상태이다.

이게 무슨말이냐면 message의 값이 변경될때 마다 reversedMessage가 실행된다는 얘기다.

 

이쯤되면 의아한게 methods에서 선언해도 값이 바뀌면 실행되는거 아닌가? 라고 의문을 가질 수 있는데

여기서 computed가장 큰 특징속성의 캐싱이 나온다.

 

캐싱이라는 특징을 보기 위해 다시 코드를 살펴보자.

 

1-1 computed 캐싱

<div id="example">
  <p>computed: {{ computedCount }}</p>
  <p>method: {{ methodsCount() }}</p>
  <button @click='count1++'>computedCount</button>
  <button @click='count2++'>methodsCount</button>
</div>
var vm = new Vue({
  el: '#example',
  data: {
    count1 : 0,
    count2 : 0
  },
  computed: {
    computedCount: function () {
      console.log('computed 감지');
      return this.count1
    }
  },
  methods: {
     methodsCount: function () {
      console.log('methods 감지');
      return this.count2
    }
  }
})

 

이런식으로 되어있다면 결과가 어떻게 될까?

둘다 당연히 count를 정상적으로 뿌려주긴할텐데 console.log에 찍히는게 문제가 있다.

 

버튼을 각각 두번씩 눌러본다 하면 다음과 같은 결과가 나온다.

 

▷ 결과

 

어째서 이런 결과가 나오는걸까?

위에서 설명한것 처럼 computed 속성은 종속 대상을 따라 저장(캐싱) 되는 특징을 가지고 있어서 그렇다.

그래서 종속대상의 값이 변경되지 않는다면 다시 실행되는 경우가 없으며,

methods의 경우에는 종속관계가 아니기 때문에 vue에서 데이터가 바뀔때 마다 재렌더링이 되는데 그때마다 실행되는 것이다.

 

이게 코드가 길어지고 기능이 많아지면 성능에서 아주 큰 차이가 나게 될 것이다.

 

그리고 computed의 특징 중 자잘한 몇가지는

호출할 때 괄호()를 사용할 필요가 없다는것과, 파라미터를 받을수가 없다 라는 특징을 가지고있다.

 

1-2 computed getter/setter 함수

coumputed 속성은 기본적으로 getter 함수만 가지고 있으나, 필요에 따라 setter 함수를 만들어 사용할 수 있다.

잘 사용은 하지 않지만 필요한 경우에만 사용해 주도록 하자.

 

<div id="demo">
  <p>{{ fullName }}</p>
  <button @click='fullName="John Doe"'>change</button>
</div>
var vm = new Vue({
  el: '#demo',
  data: {
    firstName: 'Foo',
    lastName: 'Bar'
  },
  computed: {
    fullName: {
      // getter
      get: function () {
        return this.firstName + ' ' + this.lastName
      },
      // setter
      set: function (newValue) {
        var names = newValue.split(' ')
        this.firstName = names[0]
        this.lastName = names[names.length - 1]
      }
    }
  }
})

 

이때 동작 원리는 버튼을 클릭할 경우 fullName = 'John Doe'가 실행되는데

computed에서의 fullName에서 반응하여 set 메서드를 먼저 실행해 firstName 과 lastName을 설정하고

그 뒤에 get 메서드를 실행하여 fullName을 반환한다.


2. watch

<div id="demo">
  <p>{{ fullName }}</p>
  <button @click='firstName="John"'>change-firstName</button>
  <button @click='lastName="Doe"'>change-lastName</button>
</div>
var vm = new Vue({
  el: '#demo',
  data: {
    firstName: 'Foo',
    lastName: 'Bar',
    fullName: 'Foo Bar'
  },
  watch: {
    firstName: function (val) {
      console.log('change-firstName');
      this.fullName = val + ' ' + this.lastName
    },
    lastName: function (val) {
      console.log('change-lastName');
      this.fullName = this.firstName + ' ' + val
    }
  }
})

 

watch 속성은 이름 그대로 감시자같은 역할을 한다 생각하면 되는데 데이터 변경을 감지하여 실행되는 특징을 가지고 있다.

 

예제를 통해 작동 원리를 직접 살펴보자면 버튼 두개를 순서대로 눌러보면 다음과 같은 결과가 나온다.

 

▷ 결과

 

firstName 과 lastName이 변경될 때만 실행된 것을 확인할 수 있다.

그래서 사용방법은 예제와 마찬가지로 watch 안에 데이터명을 입력하여 데이터 변경 감지를 해서 처리를 해주면된다.


대부분의 경우 computed 속성을 많이 사용하며 watch는 많이 사용하는 추세는 아니다.

computed와 methods의 경우 파라미터가 있고 return을 굳이 해줄필요 없는 경우 methods를 사용하며 그 외의 것은 computed를 사용해주면 좋다.

 

참고 : https://kr.vuejs.org/v2/guide/computed.html

 

computed와 watch — Vue.js

Vue.js - 프로그레시브 자바스크립트 프레임워크

kr.vuejs.org

 

반응형


댓글

TOP