Development/Vue.js

[Vue.js] Document 따라하기 - Watchers

도롱뇽도롱 2022. 6. 26. 10:00
반응형

Basic Example

Computed 속성을 사용하면 파생된 값을 선언적으로 계산할 수 있다. 그러나 상태 변경에 대한 반응으로 사이드 이펙트(DOM을 변경하거나 비동기 작업의 결과를 기반으로 다른 상태를 변경하는 것)를 수행해야 하는 경우가 있다.

 

Options API를 사용하는 경우 watch 옵션을 사용하여 반응형 속성이 변경될 때마다 함수를 실행할 수 있다.

export default {
  data() {
    return {
      question: '',
      answer: 'Questions usually contain a question mark. ;-)'
    }
  },
  watch: {
    // question이 변경될 때마다 함수 실행
    question(newQuestion, oldQuestion) {
      if (newQuestion.indexOf('?') > -1) {
        this.getAnswer()
      }
    }
  },
  methods: {
    async getAnswer() {
      this.answer = 'Thinking...'
      try {
        const res = await fetch('https://yesno.wtf/api')
        this.answer = (await res.json()).answer
      } catch (error) {
        this.answer = 'Error! Could not reach the API. ' + error
      }
    }
  }
}
<p>
  Ask a yes/no question:
  <input v-model="question" />
</p>
<p>{{ answer }}</p>

Basic Example
Basic Example

watch 옵션은 점(.)으로 구분된 경로도 지원한다.

export default {
  watch: {
    // Note: 단순 경로만 가능하며 표현식은 지원되지 않는다.
    'some.nested.key'(newValue) {
      // ...
    }
  }
}

 

Deep Watchers

watch는 기본적으로 얕다. 콜백은 watched 속성에 새 값이 할당되었을 때만 트리거 된다. 중첩된 속성 변경에는 트리거되지 않는다. 중첩된 모든 변경사항에 대해 콜백을 실행하려면 deep watcher를 사용해야 한다.

export default {
  watch: {
    someObject: {
      handler(newValue, oldValue) {
        // Note: `newValue`와 `oldValue`는 동일한 객체를 참고하고 있기 때문에
        // 다른 객체로 변환되지 않는 한 값이 동일하다.
      },
      deep: true
    }
  }
}

사항에 콜백을 실행하려면 deep watcher를 사용해야 한다.

 

사용 시 주의사항

Deep watch는 감시되는 객체의 모든 중첩 속성을 탐색하기 때문에 큰 데이터 구조에서 사용할 때 비용이 많이 들 수 있다. 성능에 영향을 주는지 고려하여 필요한 경우에만 사용해야 한다.

 

Eager Watchers

watch는 기본적으로 게으르다(lazy). 감시되는 소스가 변경될 때까지 콜백은 호출되지 않는다. 하지만 예를 들어 초기 데이터를 가져온 후 관련 상태가 변경될 때마다 데이터를 다시 가져오길 바라는 등의 경우에는 동일한 콜백 로직이 빠르게 실행되기를 원할 수 있다.

 

handler 함수와 immediate: true 옵션으로 구성된 객체를 사용하여 감시자를 선언함으로써 콜백이 즉시 실행되도록 할 수 있다.

export default {
  // ...
  watch: {
    question: {
      handler(newQuestion) {
        // component 생성 시 즉시 실행됨
      },
      // force eager callback execution
      immediate: true
    }
  }
  // ...
}

 

Callback Flush Timing

반응형 상태를 변경하면 Vue component 업데이트와 사용자가 만든 감시자 콜백이 모두 트리거될 수 있다.

 

기본적으로 사용자 생성 감시자 콜백은 Vue component가 업데이트되기 전에 호출된다. 즉, 감시자 콜백 내에서 DOM에 액세스 하려고 하면 DOM이 Vue에서 업데이트를 적용하기 전의 상태가 된다.

 

Vue가 업데이트한 후 감시자 콜백에서 DOM에 액세스하려면 flush: 'post' 옵션을 지정해야 한다.

export default {
  // ...
  watch: {
    key: {
      handler() {},
      flush: 'post'
    }
  }
}

 

this.$watch()

$watch() 인스턴스 메서드를 사용하여 감시자를 명령적으로 생성하는 것 또한 가능하다.

export default {
  created() {
    this.$watch('question', (newQuestion) => {
      // ...
    })
  }
}

이는 조건부로 감시자를 설정해야 하거나 사용자 상호 작용에 대한 응답으로만 무언가를 감시해야 할 때 유용하다. 또한 감시자를 조기에 중지할 수 있다.

 

Stopping a Watcher

watch 옵션이나 $watch() 인스턴스 메서드를 사용하여 선언된 감시자는 해당 component가 마운트 해제될 때 자동으로 중지되므로 대부분의 경우 감시자를 직접 중지하는 것에 대해 걱정할 필요가 없다.

 

해당 component가 마운트 해제되기 전 감시자를 중지해야 하는 드문 경우에 $watch() API는 이에 대한 함수를 반환하여 해당 기능을 수행할 수 있도록 한다.

const unwatch = this.$watch('foo', callback)

// ...감시자가 더 이상 필요하지 않을 때:
unwatch()

 

 

관련 Repo

https://github.com/galaxyuliana/VueExercises/tree/master/first-vue-project/src/components/Exercise/10

 

참고 자료

https://vuejs.org/guide/essentials/watchers.html

반응형