Vue.js 기초 - 컴포넌트- computed와 watch
conputed와 watch
computed와 watch는 둘 다 Vue 인스턴스 내의 정의된 데이터 값에 변경이 일어나는지를 감시하고, 변경될 때마다 정의된 함수가 실행된다. 데이터 값이 변경이 되었는지를 계속 감시한다는 측면에서 compouted와 watch는 매우 비슷해 보이지만, 사용되는 용도에는 분명 차이가 있다.
computed
데이터베이스에 사용자 정보를 저장하고 있고, 사용자의 이름을 first name과 last name으로 구분해서 저장하고 있다고 가정, 그리고 사용자 정보를 가져와서 보여주는 사용자 프로필 화면을 개발하고 있다고 가정. 화면에서는 사용자의 이름을 first name과 last name을 합쳐서 보여줘야 한다. 이 때 2가지 방법으로 구현이 가능하다.
첫 번째는 문자열 표현식인 이중 중괄호를 사용해서 2개의 데이터 값을 합쳐서 보여준다.
<template>
<div>
<h1></h1>
</div>
</template>
<script>
export default{
data(){
return{
firstName: 'SeungHyeon',
lastName: 'Kim'
};
}
}
</script>
두 번째는 사용자 이름을 합쳐서 반환하는 함수를 만들고, 함수를 호출해서 보여준다.
<template>
<div>
<h1></h1>
</div>
</template>
<script>
export default{
data(){
return{
firstName: 'SeungHyeon',
lastName: 'Kim'
};
},
methods:{
getFullName(){
return this.firstName + '' + this.lastName
}
}
}
</script>
만약 사용자 이름을 한 곳이 아니라 화면 내에서 여러 곳에서 보여줘야 한다고 가정한다면, 첫 번째 방법과 두 번째 방법 모두 데이터 결합과 함수 호출이라는 연산을 화면에 보여주는 수만큼 해야한다.
conputed는 Vue 인스턴스 내에 정의된 데이터 값과 연관된 또 하나의 데이터를 정의해서 사용할 수 있도록 해준다.
<template>
<div>
<h1>Full Name : </h1>
</div>
</template>
<script>
export default{
data(){
return{
firstName: 'SeungHyeon',
lastName: 'Kim'
};
},
computed:{
fullName(){
return this.firstName + '' + this.lastName
}
}
}
</script>
computed 내에 fullName이 정의되어 있고, firstName과 lastName을 합쳐서 반환해주는 함수로 정의되어 있다. 여기서 함수명인 fullName은 함수이자 동시에 Vue 인스턴스의 데이터 키 값이다. firstName, lastName을 인스턴스의 데이터 값으로 사용하는 것과 동일한 데이터 값으로 선언되는 것이다.
이 블로그 글의 처음에 computed는 데이터 값에 변경이 일어나는지 감시한다고 작성했다. computed로 정의하면 fullName 함수가 실행되어 데이터 fullName에 firstName과 lastName을 합ㅊ한 값이 할당된다. 그리고 firstName 혹은 lastName 값 중 하나라도 변경이 일어나면 fullName 함수가 자동으로 실행되고, fullName 값이 갱신된다.
정리하자면 computed에 정의된 fullName은 함수이자 동시에 Vue 인스턴스의 데이터이다. computed에 정의해서 사용하면 화면 내 여러 곳에서 fullName을 사용하더라도 이중 중괄호 사용과 달리 이에 대한 연산은 한 번밖에 일어나지 않는다. 문자열 표현식인 이중 중괄호 안에서 2개의 데이터 값을 합하는 연산과 함수로 구현된 연산이 화면에서 보이는 수만큼 호출되어 연산을 다시 하는 것과 큰 차이가 있다.
또한, 함수를 이용해서 fullName을 계산하는 경우는 firstName 혹은 lastName에 변경이 일어났을 떄를 감지할 수 없다.
watch
watch 역시 computed처럼 Vue 인스턴스에 정의된 데이터 값이 변경이 일어나는지를 감시하고 변경이 일어나면 지정된 함수를 실행시킬 수 있다. 하지만 computed의 경우는 기존에 정의된 데이터 값을 기반으로 새로운 데이터 값을 활용하기 위해서 사용이 된다면 watch는 watch에 정의된 데이터 값 하나만을 감시하기 위한 용도로 사용된다.
또한 watch의 경우는 computed와 다르게 실제 데이터 변경이 일어나기 전까지는 실행되지 않는다. 즉, 초기에 지정된 값인 firstName과 lastName에 값이 있음에도 불구하고 fullName은 여전히 아무런 값도 할당되지 않는다. ===> firstName과 lastName의 초기에 할당된 값이 반드시 변경이 일어나야만 watch가 실행된다.
<template>
<div>
<h1>Full Name : </h1>
</div>
</template>
<script>
export default{
data(){
return{
firstName: 'SeungHyeon',
lastName: 'Kim',
fullName: ''
};
},
watch:{
firstName(){
this.fullName = this.firstName + ' ' + this.lastName
},
lastName(){
this.fullName = this.firstName + ' ' + this.lastName
}
}
}
</script>
코드를 실행하면 아래 화면처럼 fullName 값인 이중 중괄호에는 아무런 값도 들어가 있지 않는다.
버튼을 추가하고 버튼을 클릭하면 변수 하나의 값을 변경해보자
<template>
<div>
<h1>Full Name : </h1>
<button type="button" @click="changeName">변경</button>
</div>
</template>
<script>
export default{
data(){
return{
firstName: 'SeungHyeon',
lastName: 'Kim',
fullName: ''
};
},
watch:{
firstName(){
this.fullName = this.firstName + ' ' + this.lastName
},
lastName(){
this.fullName = this.firstName + ' ' + this.lastName
}
},
methods:{
changeName(){
this.firstName = 'Hyeon';
}
}
}
</script>
vue 컴포넌트를 실행하면 처음에는 FullName이 보이지 않지만 버튼을 클릭하면 firstName 변경으로 인해 watch가 실행되고, firstName 함수를 통해 fullName이 갱신된다.
이처럼 computed는 정의된 데이터 값을 바탕으로 새로운 데이터 값을 생성하고, 새로운 데이터 값에서 참조하고 있는 기존 데이터의 값의 변경을 감지한다. 그리고 참조하고 있는 데이터의 값의 변경과 상관없이 최초에 computed에 정의된 데이터 함수를 실행한다.
watch는 초기에 할당된 값에서 변경이 일어나야 watch에 정의한 함수를 실행한다는 차이가 있다.
댓글남기기