Vue Computed와 Watch
computed와 watch의 사용 목적
computed와 watch는 모두 vue 내에서 정의된 데이터 값에 변경이 일어나는 지를 확인하고, 변경될 때마다 정의된 함수를 실행시키기 위해 사용됩니다.
computed와 watch를 사용하지 않았을 때
firstname과 lastname이라는 문자열 데이터를 합하여 fullname을 화면에 보여주는 경우를 생각해봅시다.
코드 내에서 두 개의 데이터를 합할 수도 있고, 두 데이터를 합한 값을 반환하는 함수를 만들어 사용할 수도 있을 것입니다.
<template>
<div>Concat variable: {{(firstName + ' ' + lastName)}}</div>
<div>Concat with function: {{getFullName()}}</div>
</template>
<script>
export default {
data() {
return {
firstName: 'Andy',
lastName: 'Park'
};
},
methods: {
getFullName() {
return this.firstName + ' ' + this.lastName
}
}
}
</script>
위 코드에서 첫번째 줄은 데이터를 코드 내에서 합하여 화면에 띄웠고, 두번째 줄은 데이터를 합하여 반환하는 함수를 이용하여 fullname을 화면에 띄웠습니다.
코드 수행 결과 아래 사진과 같은 내용이 화면에 보이게 됩니다.
위의 두 경우에도 데이터는 정확하게 화면에 보여집니다.
그러나 화면의 여러 부분에 해당 데이터를 보여줘야 한다면, 데이터를 합치는 연산을 여러번 해야한다는 단점이 있습니다.
Computed
Computed는 정의된 데이터 값과 연관된 또 다른 데이터를 정의해서 사용할 수 있도록 해줍니다.
위와 동일하게 동작하도록 computed를 사용하여 코드를 작성하도록 하겠습니다.
<template>
<div>Concat by Computed: {{fullName}}</div>
</template>
<script>
export default {
data() {
return {
firstName: 'Andy',
lastName: 'Park'
};
},
computed: {
fullName() {
return this.firstName + ' ' + this.lastName;
}
}
}
</script>
computed 내에 정의된 fullName은 this.firstName + ' ' + this.lastName
값을 반환하는 함수인 동시에 데이터의 키값이 됩니다.
computed로 데이터를 정의하면 함수가 실행되어 지정한 로직에 따라 fullName에 값을 할당하게 됩니다.
그리고 computed내에 사용되는 값 중 하나라도 변경되면 fullName 함수가 자동으로 실행되고, fullName 데이터의 값이 변경됩니다.
즉 computed에 정의된 fullName은 함수이자 동시에 vue 인스턴스의 데이터 입니다.
computed에서 정의된 데이터는 화면 내 여러 곳에서 사용되어도 이에 대한 연산은 한 번밖에 일어나지 않습니다.
Watch
Watch도 Computed처럼 데이터의 변경이 일어나는 지 감시하고, 변경이 일어나면 지정된 함수를 실행하여 데이터의 값을 업데이트합니다.
computed와 watch의 차이점으로는 computed는 기존에 정의된 값을 기반으로 새로운 데이터 값을 생성하기 위해 사용되지만 watch는 watch에 정의된 데이터 값 하나만을 감시하기 위한 용도로 사용됩니다.
또한 watch는 데이터 변경이 일어나야지만 실행되므로, 초기에 지정된 값에 대해서는 함수가 실행되지 않습니다.
watch를 사용하는 방식은 아래 코드와 같습니다.
<template>
<div>Concat by Watch: {{fullNameByWatch}}</div>
</template>
<script>
export default {
data() {
return {
firstName: 'Andy',
lastName: 'Park',
fullNameByWatch: ''
};
}
watch: {
firstName() {
this.fullNameByWatch = this.firstName + ' ' + this.lastName;
},
lastName() {
this.fullNameByWatch = this.firstName + ' ' + this.lastName;
}
}
}
</script>
위에서 사용한 코드를 모두 종합해보고, firstName과 매핑된 input을 주어 이름을 바꿀 수 있도록 해보았습니다.
<template>
<input type="text" v-model="firstName" />
<div>Concat variable: {{(firstName + ' ' + lastName)}}</div>
<div>Concat by function: {{getFullName()}}</div>
<div>Concat by Computed: {{fullName}}</div>
<div>Concat by Watch: {{fullNameByWatch}}</div>
</template>
<script>
export default {
data() {
return {
firstName: 'Andy',
lastName: 'Park',
fullNameByWatch: ''
};
},
methods: {
getFullName() {
return this.firstName + ' ' + this.lastName;
}
},
computed: {
fullName() {
return this.firstName + ' ' + this.lastName;
}
},
watch: {
firstName() {
this.fullNameByWatch = this.firstName + ' ' + this.lastName;
},
lastName() {
this.fullNameByWatch = this.firstName + ' ' + this.lastName;
}
}
}
</script>
firstName에 변경이 없을 때 나타나는 화면은 아래와 같습니다.
Watch를 통해 만든 데이터에는 아직 값이 생성되지 않았음을 확인할 수 있습니다.
input창 내의 firstName을 변경해보도록 하겠습니다.
watch로 인해 생성되는 데이터까지 값이 잘 들어갔음을 확인할 수 있습니다.