inflearn logo
강의

강의

N
챌린지

챌린지

멘토링

멘토링

N
클립

클립

로드맵

로드맵

지식공유

Typescript with Vue 실전 프로젝트

@Watch로 데이터 변화 감지하기

@Watch 질문 드립니다!

646

frontzero

작성한 질문수 8

1

안녕하세요? watch 속성 질문 드립니다.

 

<div>
<p>
@Watch
</p>
<button @click="changeMessage">메세지 변경</button>
<div>{{cMsg}}</div>
</div>

 

import { Component, Vue, Watch } from 'vue-property-decorator';
export default class Home extends Vue {
public message: string = 'hello children';
public cMsg: string | undefined;
public alertMsg: string = '변경이 감지되었습니다.';

// immediate : 즉시 호출하겠다는 의미.
// deep : object 내의 속성값까지 감시.
// @Watch('cMsg', {immediate: true, deep: true})
@Watch('cMsg')
public watchAlertMsg(value: string | undefined, oldValue: string | undefined) {
console.log(value);
console.log(oldValue);
alert(this.alertMsg);
}

public changeMessage() {
this.cMsg = 'change';
}

}

 

위와 같이 코딩을 했는데, 

cMsg 상태변수에 '' 이런식으로 초기화를 해둔경우는 정상적으로 동작을 하는데,

위와 같이 하면 왜 변경감지가 안되는지 알고싶습니다.

TS를 사용안한 vue에서는 테스트를 해보지는 못했습니다..ㄷㄷ

 

public cMsg: string | undefined = '';

위와 같이 초기화를 해주면,

옆에 사진과 같이, 해당 컴포넌트 상태변수로 존재합니다. 

= ''; 구문을 빼면, 상태변수 자체도 안보이구요

 

제가 TS구문을 잘 몰라서 이런거 같기는 한데.. 

public cMsg: string | undefined

해당 상태변수에 문자열 또는 undefined 가 할당이 될수 있어 이거 아닌가요? 그러면 제 생각은

cMsg = undefined; 이런거니 여기서 값이 바뀌면 감지가 되야 하는거같은데..ㅠㅠ 어렵네요

 
 
watch: {
testWatch(after, before) {
console.log('감지?');
console.log(before);
console.log(after);
}
},

data() {
return {
testWatch : undefined,
};
}

위 와 같이 하면, 정상적으로 감지(값을 변경할때마다)가 되어서 watch 속성 콜백함수가 호출이 됩니다.

TS 당신은 왜..ㅠㅠ

vuejs

답변 2

1

성도희

안녕하세요! ChangHyeon Bae님!

Watch는 데이터의 변경을 관찰합니다.

질문 주신 케이스에서 Watch가 동작하지 않는 이유는,
cMsg라는 속성이 없기 때문입니다. 없는 속성에 Watch를 설정해놓은 것과 마찬가지지요.

public cMsg: string | undefined ;

위와 같이 분명히 선언했는데 왜 없을까요?

그 이유는, vue-cli로 코드를 빌드하면, webpack과 ts-loader로
타입스크립트 문법을 자바스크립트로 컴파일을 하게 됩니다.
이 때 프로퍼티를 확인해서 값이 할당된 프로퍼티만 객체의 속성으로 추가하기 때문입니다.

public cMsg: string | undefined = undefined;

또한 위와 같은 코드도 동일하게 동작하지 않습니다.

Vue 공식 문서에서 아래와 같이 설명하고 있습니다.

"Vue는 루트 수준의 반응성 속성을 동적으로 추가 할 수 없으므로
모든 루트 수준의 반응성 데이터 속성을 빈 값으로라도 초기에 선언하여 Vue 인스턴스를 초기화해야합니다."

export default class Home extends Vue {
public cMsg: string | undefined;

created() {
// undefined;
console.log(this);
}
}

위와 같이 created hook에서 this를 콘솔로 출력해보면,
cMsg라는 속성은 없는것을 확인하실 수 있습니다.

그래서 이로인해 발생하는 문제점을 막기 위해 타입스크립트에서는
tsconfig.json에 특별한 설정을 하지 않거나, !를 붙이지 않은 클래스 프로퍼티에 대해서는
에러를 발생하고 있습니다.

@Prop과 같이 특수한 경우가 아닐때는 반드시 undefined가 아닌 값으로 초기화 해주시기 바랍니다.
(공통된 빈값이 필요한 경우에는 null을 사용하세요.)

참고로, changeMessage라는 메서드에서 값을 할당하고 있긴 하지만,
이 경우에는 값을 수정하는것이 아닌 속성을 "추가"하는 것입니다!

Vue의 Watch는 속성의 추가/제거에 대해 감지할 수 없는 한계를 가지고 있습니다.
(자세한 내용은 https://kr.vuejs.org/v2/guide/reactivity.html<- 링크를 방문하세요.)

0

frontzero

친절한 답변 정말로 감사합니다!

결론은 data 옵션에 해당 상태변수 자체가 존재하지 않는 상태에서 watch를 걸어버린거네요 ㅠㅠ

 

그래도 여전히 읽어보면서 의문인건.

 

public cMsg: string | undefined = undefined;

TS로 초기화 해준 undefined와

 

<template>
<div>
<button @click="changeValue">
watch 감지!
</button>
</div>
</template>

<script>
export default {
name: "Watch",

watch : {
changeVal(value, oldValue) {
console.log('감지?');
console.log(value);
console.log(oldValue);
},
},

data(){
return {
changeVal : undefined
}
},

methods : {
changeValue() {
this.changeVal = Math.floor(Math.random() * 10) + 1; // 1 ~ 10 난수 생성
}
}
}
</script>

<style scoped>

</style>

SFC 방식으로 한, 이거에 동작 차이는 역시 아직도 의문이네요.

 

소스 공유좀 해주세요

0

252

0

target null 에러뜨시는 분들

0

331

0

라우터 구조잡기 소스

0

285

0

새로 추가한 인스턴스 상태 관리

0

247

0

App.vue의 $store

0

193

0

npm run serve 에러

0

221

0

Cannot find module '@/components/message.vue' or its corresponding type declarations.

0

1152

2

prop !

0

194

0

@ MutationActions

0

179

0

mapGetters 내 정의가 안되요 ㅠ

0

260

0

안녕하세요! @Prop() readonly id(느낌표):string; 에서 !(느낌표) 를 찍는 이유가 궁금합니다 :)

0

227

0

store 사용 방법 관련 질문입니다.

0

240

1

moduleA.store.ts내에서 RootState가 하는일은 무엇인가요?

0

179

0

removeItem 에서 element 가 하나 남았을 때 삭제가 되지 않는 문제

0

373

2

Property '$route' does not exist on type 'ItemList'. 이 에러는 무엇인가요..?

0

862

1

Cannot find module '@/components/message.vue'.

0

2873

6

@Action, @Mutation 등으로 지정된 변수의 타입

0

231

1

안녕하세요. 강의 잘 들었습니다.

0

168

0

Axios Post보낼때 어떤 식으로 구성하는게 좋을까요?

0

663

1

안녕하세요! v-for(v-bind:key), slice() 관련 질문이 있어요!

2

667

3

에러 표시 질문이요!

1

403

3

vuex-module-decorators 보다 오리지널 모듈 형태를 선호하시는 이유가 무엇이신가요?

1

381

2

안녕하세요. 초기 셋팅시 질문있습니다.

1

296

2

안녕하세요! Vuex, actions 질문이 있습니다.

1

305

2