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

    2022. 8. 12.

    by. 웰시코더

    반응형

    - 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

     

    반응형

    댓글