watch
vue
에서 watch
속성은 값이 변경될때 이에 대한 부수 효과 (비동기 통신을 통한 재호출, 변경된 값에 대한 DOM조작 등등 ) 을 처리할대 유용하게 사용되는 속성입니다. 그러나 기본타입이 아닌 중첩된 같은 값의 변경을 감지할때는 문제가 있습니다.
Object 데이터 watch
우선 다음과 같이 parent 컴포넌트와 child 컴포넌트를 작성해주도록 하겠습니다. 각 컴포넌트의 역활은 다음과 같습니다.
- parent 컴포넌트 : data 오브젝트를 자식컴포넌트로 내려주고 버튼 클릭시 data 오브젝트의 count를 증가 시켜줍니다.
- children 컴포넌트 : parent 로 받은 data 오브젝트의 count를 보여주고 data 속성을 watch 로 변경시 console.log 를 보여주도록 합니다.
parent 컴포넌트
<template>
<div>
<button @click="increase">숫자 증가</button>
<children :parent-data="data"/>
</div>
</template>
<script>
import Children from './children';
export default {
name: 'parent',
components: {Children},
methods: {
increase() {
this.data.count = this.data.count + 1;
},
},
data() {
return {
data: {
count: 0,
},
};
},
};
</script>
<style scoped></style>
child 컴포넌트
<template>
<div>
<div>
<span>카운트 {{parentData.count}}</span>
</div>
</div>
</template>
<script>
export default {
name: 'children',
watch: {
parentData(newData) {
console.log(`data change ${newData}`)
},
},
props: {
parentData: {
type: Object,
default() {
return {};
},
},
},
};
</script>
<style scoped></style>
위에서 작성한 컴포넌트를 실행시켜본 결과는 다음과 같습니다.

예상했던것처럼 data의 count 를 변경할 경우 이에대해 변경된 값으로 바꾸어 보여주지만 watch 속성에서는 변경된 것을 감지하지 못하고 있습니다.
watch - deep 속성
이러한 Object의 중첩된 값의 변경을 감지하고 싶다면 아주 간단하게 watch의 속성인 deep
을 추가해 주면 감지할 수 있습니다. 해당 속성을 적용하여 child 컴포넌트를 수정해 주도록 하겠습니다.
deep 속성을 적용한 child 컴포넌트
<template>
<div>
<div>
<span>카운트 {{parentData.count}}</span>
</div>
</div>
</template>
<script>
export default {
name: 'children',
watch: {
parentData: {
deep: true,
handler(newData) {
console.log(`data change ${newData.count}`)
},
},
},
props: {
parentData: {
type: Object,
default() {
return {};
},
},
},
};
</script>
<style scoped></style>
위의 수정한 컴포넌트를 보면 중첩된 데이터의 감지를 위해 deep 속성을 추가 된 것을 볼 수 있습니다. 이때 handler 함수는 해당 값이 변경될 경우 호출되는 함수입니다. 즉 맨처음 선언한 파라미터가 없는 watch 속성은 아래 코드의 단축표현 입니다.
watch: {
parentData {
handler(newData){
console.log(`data change ${newData}`)
}
},
},
이제 수정한 결과를 확인해보도록 하겠습니다.

짜잔 다음과 같이 정상적으로 변경된 것을 감지한 것을 확인할 수 있습니다. :)
참조