본문 바로가기
개발자 일지/Vue.js

watch를 통해 객체 중첩 값 변경 감지하기

by 네빌링 2022. 8. 12.
반응형

- watch 속성 기능에 대해 살펴본다.

- 일반적으로 watch는 객체 내부 데이터 변경 감지를 할 수 없는데, 이를 해결하는 방법을 알아본다.


 

1.watch

 

Vue.js에서 데이터를 감지할 때 watch 속성을 사용한다. 특정 프로퍼티가 변경될 때 지정한 콜백함수가 실행되는 기능이다.

 

computed랑 비슷하다. 

 

둘을 혼동하는 경우가 많아서 블로그에 찾아봤는데,

 

https://blog.jeongwoo.in/vue-js-watch%EC%99%80-computed-%EC%9D%98-%EC%B0%A8%EC%9D%B4%EC%99%80-%EC%82%AC%EC%9A%A9%EB%B2%95-e2edce37ec34

 

[Vue.js] watch와 computed 의 차이와 사용법

Vue.js에서 computed 프로퍼티는 매우 유용하게 사용된다. 그러나 처음 Vue.js를 시작할때 computed와 watch가 모두 반응형이라는 키워드과 관련이 있기 때문에 이 둘을 혼동하곤 했다. Vue.js의 강점을 잘

blog.jeongwoo.in

 

이 블로그에서 잘 설명해주는 것 같다. 이해가 쉽지는 않은데..핵심을 정리하자면 종속관계인 것 같은데 종속관계가 복잡해질 때 watch를 사용하면 코드복잡도가 올라간다고 한다. (종속관계에 대해서는 위 블로그 참고)

 

2.watch를 사용하는 방법

 

1)일반적인 방법으로 watch를 호출했을 때

 

장르를 공포로 바꾸었는데 아무런 console.log가 안 찍힘

 

영화 검색을 위해 장르를 '공포'를 선택하면 watch를 통해 콘솔로그를 찍도록 감지하고 싶었다. 

 

저 셀렉트박스 '장르'관련 코드는 다음과 같이 구성되어있다.

 

<html>
	<body>
    	<!-- 생략.. -->
    	<label for="genre" class="form-label">장르</label>
        <select id="genre" class="form-select" v-model="reqData.genre">
            <option value="">전체</option>
            <option v-for="(genre, i) in initData.genre" 
            		:id="'genre_' + genre.code" 
                    :key="i" :selected="i == 0" 
                    :value="genre.code">
                {{genre.name}}
            </option>
        </select>
        <!-- 생략.. -->
    </body>
</html>
<script>
    const app = new Vue({
    	el:"#app",
        data: {
        	//...
            reqData: {
              genre: '',
              title: '',
              country: '',
            },
            movieList: []
        },
        created() {
            //...
        },
        methods: {
            //...
        },
        watch : {
        	//reqData 내부의 genre 데이터 변경시 watch가 작동 안 함
            reqData() {
            	console.log('장르변경:', this.reqData.genre);
            }
        }
        
    });
</script>

 

셀렉트박스의 v-model이 reqData.genre와 매핑되어 있기 때문에 셀렉트박스 선택시 바뀐 값이 reqData.genre에 들어간다.

 

참고로 :value를 지정안해주면 그냥 <option>태그의 내부 text가 들어간다. :value를 지정해줘야 :value값이 reqData.genre에 들어간다. 원래 이랬었던가? 너무 오랜만에 해서 가물가물하다.

 

어쨋뜬 저 내부 변경을 감지하는 방법은 2가지 정도로 볼 수 있다.

 

2)watch 객체 내부 감지 방법1

 

다음과 같이 처리한다.

watch: {
    //요렇게 해도 됨
    'reqData.genre' () {
        console.log('장르변경!', this.reqData.genre);
    }
}

 

콘솔로그가 찍힌다.

 

 

 

 

3)watch 객체 내부 감지 방법2

 

찾아보니 이 방법을 더 선호하는 것 같다. 다음과 같이 watch 코드를 변경해준다.

 

watch: {
    //권장 방법
    reqData: {
        deep: true,
        handler() {
            console.log('reqData 장르 변경:', this.reqData.genre);
        }
    }
}

 

다음과 같이 감지됨을 확인할 수 있다.

콘솔로그가 찍힌다.

 

 

위와 같이 watch 내부에 deep 속성을 지정해줄 수 있다. 말 그대로 객체 내부를 deep하게 감지하라는 것인듯?

handler는 변경될 때 호출될 함수를 지정한다.

 

 

참조

https://ui.toast.com/weekly-pick/ko_20190307

https://blog.woolta.com/categories/10/posts/196

 

반응형