vue - watch

오민영·2021년 7월 29일
0

Vue.js

목록 보기
3/10
post-thumbnail

특정 데이터의 변화를(stateprops) 감지하고, 해당 값이 변경되었을 때, 자동으로 특정 로직을 수행하는 역할을 한다. 데이터 변경에 의한 응답으로 비동기식, 또는 시간이 많이 소요되는 조작을 수행하려는 경우에 가장 유용하다!

watch 옵션을 사용하면 비동기 연산(API)를 수행하고, 그 연산을 얼마나 자주 수행할지 제한하며, 최종 응답을 얻을 때까지 중간 상태를 설정할 수 있다.
(watch는 유용하게 사용할 수 있지만, computed 속성만으로도 충분한 문제를 해결할 수 있다.)

예시

message 데이터에 watch 속성을 지정한 코드로, message의 데이터가 변할 때마다 watch 속성에 정의한 message 함수가 실행되면서 콘솔에 데이터를 출력한다.

new Vue({
  data() {
    return {
      message: 'Hello'
    }
  },
  watch: {
    'message': {
      handler(value, oldValue) {
        console.log(value);
      },
      immediate: true // 컴포넌트가 생성되자마자 즉시 실행
    }
  }
})

watch 속성

deep - 중첩된 data watch하기 (배열 / 객체)

배열이나 객체를 watch할 때, 예상대로 동작하지 않는다.

const array = [1, 2, 3, 4];
// array = [1, 2, 3, 4]

array.push(5);
array.push(6);
array.push(7);
// array = [1, 2, 3, 4, 5, 6, 7]
  • 배열에 push를 사용해서 값을 넣어줬을 경우, 배열의 내용은 변경되었지만 변수(array)는 여전히 같은 array를 가리킨다. 즉, 배열 컨테이너는 변경되지 않았지만, 배열 내부는 변경되었다. (다시 조회하지 않는 이상, 기존 array를 가리키고 있는 것처럼 보인다)

  • 따라서 vue는 배열이나 객체를 watch할 때 속성 내부가 변경되었다고 생각하지 않기 때문에, vue에게 변경을 watch 할 때, 속성 내부를 검사하길 원한다고 알려줘야 한다.

  • 위와 같이 실시간으로 검사를 하고자 할 경우, deep 속성과 handler 메서드를 재배치 함으로써 vue에게 원하는 바를 알려주도록 한다.

export default {
  name: 'ColourChange',
  props: {
    colours: {
      type: Array,
      required: true,
    },
  },
  watch: {
    colours: {
      // 배열 내부를 검사하여, 알려준다.
      deep: true,

      // We have to move our method to a handler field
      handler()
        console.log('The list of colours has changed!');
      }
    }
  }
}

immediate - 처음 꼭 실행하기

속성 값이 변할 때 watch가 실행되지만, 변경과 관계없이 최초 처음 한 번 실행을 하고자 할 때 사용하는 속성이다.

예제

movie 속성 설정에 따라서 서버에서 데이터를 가져오는 MovieData 컴포넌트

export default {
  name: 'MovieData',
  props: {
    movie: {
      type: String,
      required: true,
    }
  },
  data() {
    return {
      movieData: {},
    }
  },

  watch: {
    // Whenever the movie prop changes, fetch new data
    movie(movie) {
      // Fetch data about the movie
      fetch(`/${movie}`).then((data) => {
        this.movieData = data;
      });
    }
  }
}

위 예시에서 보면, movie 속성이 변경될 때마다 watch가 실행되고 새로운 데이터를 가져와서 반영한다.

여기서 작은 문제,

  • 페이지가 로드될 때 movie가 기본값으로 설정이 되는데, 데이터 속성이 아직 변경되지 않았음으로 watch는 실행되지 않는다.
  • 즉, 다른 동영상을 선택할 때까지 데이터가 로드되지 않음을 의미한다.

위 문제를 해결하기 위해서는, (페이지 로드 시, 즉시 watch가 실행 되도록), immediatetrue로 설정하고, 메서드를 handler 함수에 옮겨준다.

watch: {
  // Whenever the movie prop changes, fetch new data
  movie: {
    // Will fire as soon as the component is created
    immediate: true,
    handler(movie) {
      // Fetch data about the movie
      fetch(`/${movie}`).then((data) => {
        this.movieData = data;
      });
    }
  }
}

handler

handler는 watch 된 속성이 변경될 때, 호출될 함수를 지정할 수 있다.

watch: {
  movie: {
    handler(movie) {
      // Fetch data about the movie
      fetch(`/${movie}`).then((data) => {
        this.movieData = data;
      });
    }
  }
}

// 단축표현
watch: {
  movie(movie) {
    // Fetch data about the movie
    fetch(`/${movie}`).then((data) => {
      this.movieData = data;
    });
  }
}

Reference

참고
참고

profile
이것저것 정리하는 공간

0개의 댓글