간단한 로직 같은 경우에는 에 넣어도 가능하지만,
<div id="example"> {{ message.split('').reverse().join('') }} </div>
위와 같은 경우에는 너무 많은 연산이 템플릿 안에 들어가서 코드가 비대해지고 유지보수가 어렵습니다.
이와 같은 이유들로 복잡한 로직이라면 반드시 computed 속성 을 사용해야 하는 이유입니다
html
<div id="app">
<p>원본 메시지: "{{ message }}"</p>
<p>역순으로 표시한 메시지: "{{ reversedMessage }}"</p>
</div>
js
<script>
new Vue({
el: '#app',
data: {
message: '안녕하시렵니까'
},
methods: {},
computed: {
// 계산된 getter
reversedMessage: function() {
// `this` 는 vm 인스턴스를 가리킵니다.
return this.message
.split('')
.reverse()
.join('');
}
}
});
</script>
유지보수 측면에서의 예시를 살펴보자면,
<div id="app">
{{ message.split('').reverse().join('') }}
{{ message.split('').reverse().join('') }}
{{ message.split('').reverse().join('') }}
</div>
만약 메세지를 바꿔야한다면 세가지 모두를 찾아내어 바꿔야한다. 하지만 computed 를 사용하게되면
computed: {
// 계산된 getter
reversedMessage: function() {
// `this` 는 vm 인스턴스를 가리킵니다.
return this.message
.split('')
.reverse()
.join('');
}
}
computed에서 바꿔 줄 수 있다. 즉, React의 component의 재사용과 많은 공통점이 있다고 볼 수 있다.
computed에 사용된 경우에는
template안에 바로
<p>역순으로 표시한 메시지: "{{ reversedMessage }}"</p>
computed: {
// 계산된 getter
reversedMessage() {
// `this` 는 vm 인스턴스를 가리킵니다.
return this.message
.split('')
.reverse()
.join('');
}
}
으로 사용해도 된지만, method에 정의된 경우에는
<p>역순으로 표시한 메시지: "{{ reversedMessage() }}"</p>
computed: {
// 계산된 getter
reversedMessage() {
// `this` 는 vm 인스턴스를 가리킵니다.
return this.message
.split('')
.reverse()
.join('');
}
}
reversedMessage( ) 이렇게 소괄호를 꼭 써주어야한다.
그렇다면 computed와 메소드 는 어떤 차이점을 가지고 있을까?
최종 결과에 대해 두 가지 접근 방식은 서로 동일합니다. computed속성은 캐싱을 하고 method는 캐싱을 하지 않는다는 것이다.
computed 속성은 종속 대상을 따라 저장(캐싱)된다는 것 입니다. computed 속성은 해당 속성이 종속된 대상이 변경될 때만 함수를 실행합니다.
즉 message가 변경되지 않는 한, computed 속성 인 reversedMessage를 여러 번 요청해도 계산을 다시 하지 않고 계산되어 있던 결과를 즉시 반환합니다.
그렇다는건 메소드 의 경우에는 reversedMessage가 요청될 때 마다 data에서 message를 가져와서 계산을 한 다음에 return해준다.
=> computed는 미리 값을 계산하여 가지고 있다 = 캐싱!
예를 통해 살펴보면,
computed속성
<div id="app">
{{ reversedMessage }}
{{ reversedMessage }}
{{ reversedMessage }}
</div>
template에 다음과 같이 호출을 할 때,
computed속성의 경우에는 미리 reversedMessage를 계산하고 있다고 값을 주고
메소드
<div id="app">
{{ reversedMessage() }}
{{ reversedMessage() }}
{{ reversedMessage() }}
</div>
메소드의 경우에는 각 각의 호출마다 다시 계산을 한다고 생각할 수 있다.
<script>
new Vue({
el: '#app',
data: {
message: '안녕하시렵니까'
},
methods: {
changeMessage() {
this.message = '권기현권기현';
}
},
computed: {
reversedMessage() {
// `this` 는 vm 인스턴스를 가리킵니다.
return this.message
.split('')
.reverse()
.join('');
}
},
watch: {
message(newVal, oldVal) {}
}
});
</script>
watch속성 안에는 감시 하고 싶은 데이터 를 함수형식 으로 써주면된다!
watch속성은 매개변수 로 new Value 와 old Value 를 받는다.
=> watch안의 message는 data의 message를 지켜보고 있다가, 변경이되면 실행이된다. 그때, 업데이트된 value가 천번째 인자로 들어보고 업데이트 되지 않은 value가 두번째 인자로 들어온다.
<div id="app">
{{ message }}<br />
<button @click="changeMessage">Click</button><br />
{{updated}}
</div>
<script>
new Vue({
el: '#app',
data: {
message: '안녕하시렵니까',
updated: '아니요'
},
methods: {
changeMessage() {
this.message = '권기현권기현';
}
},
...
},
watch: {
message(newVal, oldVal) {
console.log(newVal, oldVal);
this.updated = '네';
}
}
});
</script>
버튼을 클리하면 key이벤트에 의해 changeMessage()가 발생되어 data의 message가 변한다.
이때 data의 message를 감시하는 watch의 message가 발생되고 data의 updated를 "아니요"-> "네" 로 바꾼다.
(console.log(newVal, oldVal)를 통해 "newVal"는 "권기현권기현", "oldVal" 은 "안녕하시렵니까" 가 찍힙니다.)