✔ watch 메서드란 무엇인가?
Vue에서 데이터가 변경될 때 변화를 지켜보고 변화에 대응할 수 있다.
📃 참고문헌 https://ui.toast.com/weekly-pick/ko_20190307
기본내용 데이터명: {
handler(value) {
//value 바뀐내용
console.log(value)
}
}
export default {
data() {
return {
question: '',
answer: '질문에는 일반적으로 물음표가 포함됩니다.'
}
},
watch: {
// 질문이 변경될 때마다 이 함수가 실행됩니다
question(newQuestion, oldQuestion) {
// newQuestion = 바뀐데이터,원본데이터
if (newQuestion.indexOf('?') > -1) {
//newQuestion에 ?라는 문자가 포함 되어 있으면 getAnswer을 실행
this.getAnswer()
}
}
},
methods: {
async getAnswer() {
this.answer = '생각 중...'
try {
const res = await fetch('answer을 가지고 오는 API')
this.answer = (await res.json()).answer === 'yes' ? '네' : '아니오'
//API를 가져와서 변수에 담고 싶을 때 await
} catch (error) {
this.answer = '에러! API에 연결할 수 없습니다. ' + error
}
}
}
}
<div> 예/아니오 질문:</div>
<input v-model="question" />
<p>{{ answer }}</p>
template나 메서드에서 데이터를 업데이트해야 한다면, data 안으로 들어가야 한다.
그 후의 속성 변경에 대한 응답으로 업데이트 해야 하는 경우 watch를 사용해야 한다.
중첩된 데이터 watch하기 - 배열 또는 객체
그럼, 실제로 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]
질문이 있다. array가 변경되었는가?
글쎄, 그렇게 간단하지 않다.
배열의 내용은 변경되었지만, 변수는 여전히 같은 array 객체를 가리킨다. 배열 컨테이너는 변경되지 않았지만 배열 내부는 변경되었다. (const array = [] 랑 비슷하다고 보면된다)
const array = [] // array.push를 하면 배열 내부는 바뀌지만 배열자체는 바뀌지 않는다
const를 공부하다 보면 기존에 할당 된 값을 변경하는게 불가능 하다고 나와 있는데
const array안의 내부값을 바꾸는게 가능 한 이유도 이 때문이다
두 경우 다 재 할당 하는것이 아니기 때문에 가능하다.
따라서 Vue는 배열이나 객체를 watch할 때, 속성 내부가 변경되었다고 생각하지 않는다.
Vue에게 변경을 watch할 때 속성 내부를 검사하길 원한다고 알려줘야 한다.
다음과 같이 deep을 true로 설정하고 handler 메서드를 재배치 함으로써
Vue에게 원하는 바를 알려줄 수 있다.
export default {
name: 'ColourChange',
props: {
colours: {
type: Array,
required: true,
},
},
watch: {
colours: {
// This will let Vue know to look inside the array
deep: true,
// We have to move our method to a handler field
handler()
console.log('The list of colours has changed!');
}
}
}
}
이제 Vue는 변경 사항을 watch할 때 속성 내부의 내용을 추적해야 함을 알 것이다.
그런데 handler 함수는 무엇일까?
조금 후에 handler에 대해 알아볼 것이다. 그 보다 우선 더 중요한 watch의 immediate에 대해 알아보자.
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가 실행되도록 할 수 있을까?
immediate를 true로 설정하고 핸들러 함수를 아래처럼 옮긴다.
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 함수를 두 번이나 보았다. 이제 그게 무엇인지 다룰 때가 되었다.