Computed
연산 결과를 캐싱해주는 computed 에 대해서 알아보겠습니다.
Copy // App.vue
< template >
< div id = "app" >
{{ message }}
</ div >
</ template >
< script >
export default {
name: 'app' ,
data () {
return {
message : 'Hello Vue !!'
}
}
}
</ script >
위 처럼 "Hello Vue !!" 라는 state 값을 뒤집어서 표현하기 위해 아래와 같이 코드를 추가하였습니다.
Copy < template >
< div id = "app" >
{{ message }}
< h2 >뒤집힌 message</ h2 >
{{ message.split( "" ).reverse().join( "" ) }}
</div>
</template>
위처럼 템플릿 영역에 연산처리를 넣을 수 있습니다. 하지만 state 또는 props 가 변경될 때마다 re-render 되기 때문에 매번 연산을 해야된다는 부담이 있습니다.
이런 부담을 줄이고자 우리는 computed
라는 것을 이용하여 연산결과를 캐싱
하여 사용할 수 있습니다.
Copy < template >
< div id = "app" >
{{ message }}
< h2 >뒤집힌 message</ h2 >
{{ reversedMessage }}
</ div >
</ template >
< script >
export default {
name: 'app' ,
data () {
return {
message : 'Hello Vue !!'
}
} ,
computed: {
reversedMessage () {
return this . message .split ( "" ) .reverse () .join ( "" )
}
}
}
</ script >
computed 는 대상(ex. message) 을 따라 연산결과가 캐싱됩니다. 대상인 message 가 변경되지 않는다면 이미 연산처리된 즉, 캐싱처리되어있는 reversedMessage 를 가져옵니다.
Method 에서도 같은 역할을 할 수 있지 않나요 ?
물론 가능합니다. 결과는 같습니다. 하지만 함수의 경우는 re-render 될 때마다 실행되기 때문에 캐싱 이득을 취할 수 없습니다.
Copy methods : {
reversedMessage2 () {
return this . message .split ( "" ) .reverse () .join ( "" )
}
}
Watch
state 나 props 를 감시하고 해당 값이 변경 되었을 때의 행동을 지정할 수 있는 watch 라는 속성에 대해서 알아보겠습니다.
fistname, lastname 을 적을 수 있는 input 을 준비하고 입력된 값을 합쳐 full name 을 출력하고 싶습니다.
Copy < template >
< div id = "app" >
< input v-model = "firstname" />
< input v-model = "lastname" />
< h2 >full name</ h2 >
< span ></ span >
</ div >
</ template >
< script >
export default {
name: 'app' ,
data () {
return {
firstname : '' ,
lastname : ''
}
}
}
</ script >
먼저 watch
를 이용하여 출력해보겠습니다.
Copy export default {
name : 'app' ,
data () {
return {
firstname : '' ,
lastname : ''
}
} ,
watch : {
firstname (val) {
console .log ( 'fistname' , val)
} ,
lastname (val) {
console .log ( 'lastname' , val)
}
}
}
watch 할 대상을 적어주고 대상의 값이 변경되었을 때의 행동을 적어줍니다.
fullname 이라는 state 값을 추가하고 watch 의 값이 바뀔 때마다 fullname 의 값을 변경하도록 하였습니다.
Copy < template >
< div id = "app" >
< input v-model = "firstname" />
< input v-model = "lastname" />
< h2 >full name</ h2 >
< span >{{ fullname }}</ span >
</ div >
</ template >
< script >
export default {
name: 'app' ,
data () {
return {
firstname : '' ,
lastname : '' ,
fullname : ''
}
} ,
watch: {
firstname (val) {
this .fullname = ` ${ val } ${ this .lastname } `
} ,
lastname (val) {
this .fullname = ` ${ this .firstname } ${ val } `
}
}
}
</ script >
하지만 위같은 처리를 하기위해 watch 는 좋은방법이 아닙니다. computed 라는 더 좋은 친구가 있기 때문입니다.
watch 를 computed 로 변경하기
watch 로 fullname 을 만들기 위해서는 2개의 state (first, last name) 에 watch 를 해야했습니다. 하지만 아래와 같이 computed 를 이용하면 watch 를 할필요없이 대상을 바라보게 하는 것 만으로도 fullname 을 만들 수 있습니다.
fullname 이라는 state 도 필요없어집니다. 훨씬 더 보기 편하지 않나요 ? 관리 측면에서도 훨씬 좋습니다.
Copy < template >
< div id = "app" >
< input v-model = "firstname" />
< input v-model = "lastname" />
< h2 >full name</ h2 >
< span >{{ fullname }}</ span >
</ div >
</ template >
< script >
export default {
name: 'app' ,
data () {
return {
firstname : '' ,
lastname : '' ,
}
} ,
computed: {
fullname () {
return ` ${ this .firstname } ${ this .lastname } `
}
}
}
</ script >
watch ?.. computed ..?
두 가지 모두 같은 결과를 내는데 그러면 어떤걸 쓰면 좋은건가요 ..? watch 는 언제 변하는지 예측이 어려울때 많이 사용됩니다. 예를 들어 비동기 통신이 있습니다. 우리가 어떤 데이터를 요청했을 때 이 값이 1초뒤에 올지 2초뒤에 올지 예측이 어려울때 그 값을 watch 를 통하여 감시하고 있다가 해당 값에 대한 응답이 왔을때 후처리를 해줄 수 있습니다.
computed 는 위에서 알아본 것처럼 복잡한 연산같은 것을 캐싱처리하기 위해 사용됩니다.
각각의 용도가 있기 때문에 잘 나누어 사용하는것이 중요합니다 :)