본문 바로가기

Frontend Development/Vue.js

[Vue.js] watch 사용하기 (primitive, object ...)

대부분 Computed 변수로 사용이 가능하지만 가끔 특정 data의 값이 변하는 시점에 무언가 해주고 싶을때가 있다. 예를 들어 팝업을 띄워준다던가... 백그라운드로 데이터를 변경해야 할 때 등이다..

 

이런 경우 vue의 watch 기능이 편리하다.

 

우선 일반 primitive 변수 들에 대해서는 아래와 같이 watch 선언을 한다.

<script>
  import LeftMenu from './LeftMenu';
  import RightSearchBar from './RightSearchBar';
  import {mapActions, mapGetters} from 'vuex';

  export default {
    name: 'Header',
    components: {RightSearchBar, LeftMenu},
    data() {
      return {
        searchInput: '',
        isSearchEnable: false,
        isSearchExecuted: false,
        isOpenSearchBar: false
      };
    },
    watch: {
      // isOpenSearchBar가 변경되면 아래 핸들러가 수행이 된다. 
      isOpenSearchBar(newVal, oldVal) {
        debugger;
      }
    },

 

직접 테스트를 해보자. 크롬 디버거에서 직접 변수값을 바꾸어 보면 watch handler에서 break가 걸리는 것을 볼 수 있다. 핸들러로 넘어온 값도 이전값, 최신값 모두 정확히 넘어온다.

 

이번에는 모니터링 하려는 data가 object인 경우를 보자. object의 변화를 감지하려면 watch handler 선언시 deep: true 속성을 지정해야 한다. 그렇지 않으면 내부 property 변경이 되어도 감지를 하지 못한다.

<script>
  import LeftMenu from './LeftMenu';
  import RightSearchBar from './RightSearchBar';
  import {mapActions, mapGetters} from 'vuex';

  export default {
    name: 'Header',
    components: {RightSearchBar, LeftMenu},
    data() {
      return {
        searchInput: '',
        isSearchEnable: false,
        isSearchExecuted: false,
        isOpenSearchBar: {
          isOpen: false
        }
      };
    },
    watch: {
      // Object의 내용이 변경됨을 감지하려면 deep: true 를 명시 한다.
      isOpenSearchBar: {
        deep: true,
        handler(newVal, oldVal) {
          debugger;
        }
      },
    },

 

테스트를 해보자. 직접 data 의 property isOpen을 변경해 보면 break가 잘 걸림을 알 수 있다. 그러나 핸들러로 넘어온 값을 잘 보자.

 

 Object로 watch를 했을때 newVal, oldVal를 보면 모두 newVal로 올라옴을 볼 수 있다. Vue 공식 레퍼런스에서는 다음과 같이 밝히고 있다.

Note: when mutating (rather than replacing) an Object or an Array, the old value will be the same as new value because they reference the same Object/Array. Vue doesn’t keep a copy of the pre-mutate value.

한마디로 Object일때는 본인들은 이전 값을 보관 하지 않는다는 것이다. 이 경우에는 직접 cloneDeep으로 변수를 복사해서 새 변수를 watch하면 된다고 한다. 이점은 주의해야 하겠다.