Composition API Watch 사용설명서

2020. 12. 12. 22:59Develop/Javascript

728x90

Vue3 또는 Vue2, Nuxt.js에서는 Composition API 패턴을 사용할 것을 권장하고 있습니다.

이는 기존 Options API 대비 유지보수가 용이해진다는 장점이 있습니다.

 

https://composition-api.vuejs.org/#code-organization

 

 

단일 컴포넌트내에서 너무 많은 기능을 수행한다면, 특정 기능을 수행하는 methods, computed 등의 life cycle을 찾기가 힘들어집니다. 기존 Vue에서의 단점으로 부각되는 것이 큰 규모의 프로젝트를 수행하기 어렵다라고들 하는데

설계에 문제가 있을수도 있겠지만, 기본적으로 단일 컴포넌트에 수행되는 행위들이 많아지면서 유지보수와 추가 수정이 어려워지는 현상이 나타났었습니다.

 

기존 다른언어들에서의 Class를 살펴보면 사실 Composition이라는 방식은 객체를 생성하고 콜 하여 상속이나 믹스인을 통해 유지보수가 어려워지는 문제점을 보완하기 위한 디자인 패턴으로 부각되는 방식인데

 

Vue에서는 Options API가 객체 선언 기반이라 논리적구조를 분리하고 재사용성을 증가시키기 위한 방법으로 표현됩니다.

 

 

 

Vue의 디자인 패턴 종류

Vue에서는 크게 3가지의 패턴이 두각되는데,

  • Options API (Vue2에서 가장 많이 사용되는 방식)
  • Class Based (Typescript를 적용하면서 Options API의 유지보수성 문제를 피해 상속과 Mixin을 사용하기 시작)
  • Composition API (React Hooks를 보고 Vue에 점진적 도입, 컴포넌트로직을 유연하게 구성하기 위해 시작)

 

 

 

 

Composition API가 어찌됐건 좋은건 알고 있는 사실이니 이 제목을 보고 들어오셨을겁니다.

기존 options api에서 제공되던 data(state), methods, watch, computed, updated, destoryed등 다양한 라이프사이클을 모두 setup 함수내에서 처리합니다.

 

근데 watch에서는 특이한 문제가 있는데

 

import {ref, watch} from '@nuxtjs/composition-api'

export default {
  name: 'Modal',
  props: {
    title: {
      type: String,
      default: '',
    },
    signal: {
      type: Boolean,
      default: false,
    },
  },
  setup(props, { emit }) {
    const dialog = ref<boolean>(true)

    watch(
      props.signal,
      (newVal) => {
        dialog.value = newVal
      }
    )

    watch(dialog, (val) => {
      if (!val) {
        emit('close')
      }
    })

    return {
      dialog,
    }
  },
}

위 와 같은 상황의 코드가 있다고 한다면 dialog는 ref를 통해 정상적 상태가 tree로 부터 감시되어 가상 렌더링을 통해 동적으로 진행됩니다. watch를 통해 변화도 볼 수 있겠지요

 

그런데 props를 통해 받은 signal의 경우는 감시가 안됩니다.

아마 아래와 같은 경고문구가 콘솔에 출력되는 걸 볼 수 있습니다.

[Vue warn]: Invalid watch source: false.                                                                                                                                                                             20:03:42
      A watch source can only be a getter/effect function, a ref, a reactive object, or an array of these types.

 

props로 받은 reactive 하면서 ref한 저 데이터는 경고 콘솔 오류를 보면 getter 즉 computed처럼 들어온다는것을 알 수 있으며 이는 watch로 감시하기 위해서는 이것을 먼저 전달해주어야 합니다.

 

watch(
    () => props.signal,
    (newVal) => {
    	dialog.value = newVal
    }
)

이렇게 arrow function을 통해 대충 전달하면 정상적으로 사용할 수 있습니다.

 

728x90