[Vue.js] watch와 computed 의 차이와 사용법

Jeong Woo Ahn
4 min readMar 22, 2019

Vue.js에서 computed 프로퍼티는 매우 유용하게 사용된다. 그러나 처음 Vue.js를 시작할때 computedwatch가 모두 반응형이라는 키워드과 관련이 있기 때문에 이 둘을 혼동하곤 했다. Vue.js의 강점을 잘 살려서 코딩을 하기위해 이 두가지 키워드를 잘 알고 있어야 한다.

Computed — 반응형 getter

computed를 한마디로 얘기하자면 “반응형 getter”이다. 아래 예시를 보자. vue.js 공식가이드 문서에 나오는 예시와 동일한 로직을 옮긴것이다.

computed 프로퍼티를 보면 reverseMessage 라는 프로퍼티에 값으로 익명함수가 할당되어있다. computed에 정의하는 이 익명함수는 반드시 값을 리턴하도록 작성되야한다.

getter

computedreverseMessage 프로퍼티가 정의될때 내부적으로는 Object.defineProperty를 통해 정의되며, 이때 익명함수가 getter로 설정된다. reverseMessage 를 함수가 아니라 일반 객체처럼 사용할 수 있는점과 호출될때만 계산이 이루어지고, 계산결과가 캐싱되는 특성이 생기게 된것은 getter의 특성덕분이다(이는 methods와의 차이를 유발하는 지점이기도 하다). 하지만 바로 이점 때문에 값이 변하게 되어도 캐싱때문에 변경된 값을 인지하지 못하는 단점이 생기게된다.

반응형(reactive)

Vue.js 는 이 단점을 상쇄하고 반응형을 구현하기 위해 특별한 장치를 한다. getter 함수 내에 속한 프로퍼티의 변경여부를 추적하는 것이다.(마이구미님 글 참고) 위 예시에서는 message 를 감시하고 있다가 message의 값이 변경되면 reverseMessage 를 다시 계산한다. 결국, computed는 사용하기 편하고, 자동으로 값을 변경하고 캐싱해주는 아주 끝내주는 “반응형 getter”라 부를 수 있겠다. (반응형은 Computed뿐 아니라 Vue.js 의 전반의 주요한 특징으로 볼 수 있다.)

Watch — 반응형 콜백

변경을 감시(watch)한다는 점 때문에 computedwatch를 혼동할 수 있다.걱정할 필요는 없다. computed에 비해 watch는 단순하고 이해하기 쉽기 때문이다. watchVue 인스턴스의 특정 프로퍼티가 변경될때 지정한 콜백함수가 실행되는 기능이다. 위 예시를 응용한다면 아래와 같을 것이다.

watch를 정의한 부분(17~21)을 보면 message 프로퍼티에 익명함수가 할당되어있다. 이 익명함수가 콜백함수 역할을 할 것이고, message 프로퍼티가 변경되면 변경된 값을 콜백함수의 첫번째 인자로 전달하고, 이전 값을 두번째 인자로 전달하여 실행한다. computed가 새 프로퍼티를 생성하고 그것의 getter 로 익명함수를 설정되는 것과는 달리 watch는 아무 프로퍼티도 생성하지 않고 익명함수는 단순히 콜백함수로의 역할을 한다. watch에 명시된 프로퍼티는 감시할 대상을 의미할 뿐이다.

어떻게 사용할 것인가

  • 위의 예시처럼 인스턴스의 data에 할당된 값들 사이의 종속관계를 자동으로 세팅하고자 할때는 computed로 구현하는것이 좋다. 그러니까 reverseMessagemessage 값에 따라 결정되어진다. 이 종속관계가 조금이라도 복잡해지면 watch로 구현할 경우 중복계산이 일어나거나 코드 복잡도가 높아질 것이다. 이는 오류도 더 많이 발생시킬 것이다.
  • watch는 특정 프로퍼티의 변경시점에 특정 액션(call api, push route …)을 취하고자 할때 적합하다.
  • computed의 경우 종속관계가 복잡할 수록 재계산 시점을 예상하기 힘들기 때문에 종속관계의 값으로 계산된 결과를 리턴하는 것 외의 사이드 이펙트가 일어나는 코드를 지양해야한다.
  • 더 쉽게 판단하는 방법: 만약 computed로 구현가능한 것이라면 watch가 아니라 computed로 구현하는것이 대게의 경우 옳다.

참고 문서

이글이 마음에 드셨다면 👏🏽👏🏽, 커피한잔 후원하기 (카카오페이), 이메일 구독

--

--