본문 바로가기

Vue.js

[Udemy Vue 완벽가이드 Section2] 30. 감시자(Watcher) 활용하기

# computed 프로퍼티 복습

computed

- 동적 값을 출력하는데 핵심 기능. ex: 복수의 입력값(의존성) 또는 지금처럼 입력값 한 개와 하드코딩된 값 한 개가 있는 경우.

//HTML
<p>Your name: {{ fullname }}</p> <!--괄호없이 입력-->


//JS
computed: {
 fullname() {
  if(this.name === '') { //name이 의존성
   return '';
  }
  return this.name + ' ' + 'Schwarzu'; //입력값 name + 하드코딩된 값
 },
}

 

 

# watch 프로퍼티

Vue에 내장된 또다른 반응성 기능이 있다. 바로.... 감시자(watcher)

 

watch

- 의존성 중 하나가 변경될 때 Vue에 실행하도록 지시할 수 있는 함수.  (얼핏 들으면 computed와 비슷하다.)

- 실제로 computed 프로퍼티 대신, watch를 사용할 수 있다.

 

- watch를 실제 어떻게 작동하는지, 그리고 왜 computed와 구분해서 사용하는지 보자.

- computed 프로퍼티와 data 프로퍼티에는 같은 이름을 사용하지 않는다. (아래의 예시와 같이)

data(){
 return {
  fullname: '',
 }
},
computed: {
 fullname() {},
}

- createApp에 전달한 객체에 대한 옵션들(data, methods, computed  등) 중 하나인 watch. 위치는 상관없다.

- watch라는 이름은 변경 불가능. Vue가 지원하는 기능 중 하나.

- watch는 methods, computed와 마찬가지로 객체를 취한다. 그리고 메서드를 정의한다.

- data 프로퍼티computed 프로퍼티에서 사용한 이름을 watch 메서드에 이름으로 사용할 수 있다.

 ex: data 프로퍼티에 name이 있어도 watch에 name으로 쓸 수 있다. watch에서 메서드로 정의한다. 이름 충돌이 발생하지 않는다.

name이 변경될 때마다 watch 메서드인 name메서드는 재실행된다. data의 name이 watch에 사용되면서 연결이 설정되었다.

- data나 computed 프로퍼티 이름을 watch에서 메서드 이름으로 사용하면, data나 computed 프로퍼티에 있는 이름이 변경될 때마다 watch의 해당 메서드가 Vue에 의해 자동 실행된다.

example : 아래와 같은 경우엔, name 프로퍼티가 변경될 때마다 watch프로퍼티의 name 메서드가 자동으로 실행된다.

data(){
 return {
  name: '',
 }
},
watch: {
 name(){
  //data의 name이 변경되면 실행되어야 할 로직
 },
}

- watch프로퍼티의 name 메서드에는 사용할 logic을 명시한다.

- watch에서는 반환하는건 없다. 반환 값을 사용하기 위해 HTML코드에 watch를 사용하는건 아니니깐. 대신, name이 변경되면 실행되어야 할 로직을 입력한다.

- watch의 함수는 자동으로 마지막 값(최신 값)을 인수로 가져온다. Vue에 의해 자동으로 전달된다.

data(){
 return {
  name: '',
  fullname: '',
 }
},
watch: {
 name(){
  this.fullname = this.name + ' ' + 'Oh';
 },
},

 

 

사실, 위 식처럼 watch프로퍼티의 name함수에서 this.name을 참조할 필요도 없다. 감시자 함수는 최신 값을 인수로 가져올 수 있으므로. 원하는대로 이름을 지정한 다음, 사용할 수 있다.

watch: {
 name(value){ //value대신 다른 이름 사용가능. ex:newValue
  this.fullname = value + ' ' + 'Oh';
 },
}

 

 

value외에 두 번째 인수를 받아들일 수도 있다. 두 번째 인수는 이전 값이 된다. 원하면 이렇게 두 가지 인수를 받을 수 있다. new Value, old Value

watch: {
  name(newValue, oldValue){...},
}

 

이제 name이 변경될 때마다 fullname도 업데이트된다. input창에 입력값을 입력하면 뒤에 'Oh'도 같이 나온다. 

watch: {
 name(value){
  if(value === '') {
   this.fullname = ''
  } else {
   this.fullname = value + ' ' + 'Oh';
  }
 },
}

 

 

# computed대안으로 사용시 문제점

watch를 computed의 대안으로 사용할 수 있다. 하지만 computed프로퍼티의 대안으로 사용하면 문제가 발생하는 경우가 있다.

 

 

[ computed 프로퍼티가 두 개 이상의 의존성을 사용할 때 발생 ]

아래 코드에서 data인 name 또는 lastName이 변경될 때마다 fullname을 업데이트 해보자. watch를 이용하여 설정하려면 감시자 name과 lastName 이렇게 두 개를 추가해야한다.

<input type="text" v-model="name" />
<input type="text" v-model="lastName" />
data(){
 return {
  name: '',
  lastName: '',
  fullname: '',
 }
},
watch: {
 name(value) {
  if(value === '') {
   this.fullname = ''
  } else {
   this.fullname = value + ' ' + this.lastName;
  }
 },
 lastName(value) {
  if(value === '') {
   this.fullname = '';
  } else {
   this.fullname = this.name + ' ' + value;
  }
 }
}

 

 

name, lastName 이렇게 두 개의 감시자보다 computed 하나만으로 fullname을 동적으로 가져올 수 있다. 더 적은 코드로 원하는 동작을 얻을 수 있다.

computed: {
 fullname(){
  if(this.name === '' || this.lastName === '') {
   return '';
  }
  return this.name + ' ' + this.lastName;
 }
}

 

 

# 그럼 watch는 왜 존재하는걸까?

watch를 사용할 순 있지만 더 안좋다면, 그럼 왜 watch가 존재하는걸까?

위 코드는 watch의 주요 용도가 아니다. 다른 용도에서 watch는 강력한 도구가 된다.

 

ex: counter가 50을 초과하면 reset된다고 가정해보자. 이런 종류의 작업에서는 watch가 유용하다. 어떤 일이 발생하면 counter를 변경하는 것

* counter를 감지 counter의 최신 값을 가져오기 counter의 값이 50보다 큰지 확인하고 true인 경우, counter 값을 0으로 설정.

 

즉, data 프로퍼티를 업데이트하지만, 항상 업데이트를 하는건 아닌 로직을 실행하려는 경우에 watch가 유리.

** computed 프로퍼티의 counter값을 변경시키는건 안된다. computed property "counter" is readyonly.라는 메시지가 뜬다.

 

 

또 다른 예시:
특정 data가 변경되면 HTTP 요청 / 특정 값이 변경되면 설정하는 타이머

watch: {
 counter(value){
  if(value > 50) {
   const that = this; //메서드 호출 시, 메서드를 소유한 객체에 바인딩된다. 그래서 Vue앱.
   setTimeout(function(){
   //this.counter = 0; 이렇게는 작동하지 x. 내부함수의 this는 전역객체(window객체)에 바인딩된다.
    that.counter = 0;
   }, 2000)
  }
 }
}

 

모든 프로퍼티 변화가 아닌, 일부 프로퍼티 변화에 반응하여 data 프로퍼티를 업데이트하려는 경우, 또는 뭔가가 변경되어 코드를 실행할 땐 감시자가 유용할 수 있다.

반면, 출력값을 동적으로 계산할 때는 computed 프로퍼티가 좋다.

 

 

 

 

** 출처: 모든 내용은 Udemy Vue-완벽가이드 강의를 기반으로 작성하였습니다.