- HTML > body -
<!-- < computed 속성 vs methods 속성 > -->
<div id="app-1">
<div>
<p> original msg : {{ msg }} </p>
</div>
<div>
<p> app1.msg = "changed msg"; </p>
</div>
<div>
<p> reversed msg from computed : {{ reversedByComputed }}</p> <!--computed로부터 값을 부를 때는 함수 실행()을 하지 않고 data 속성 변수처럼 부릅니다.-->
</div>
<div>
<p> reversed msg from methods : {{ reversedByMethods() }} </p> <!-- 실행시킬 때는 함수명() 소괄호 붙여주기 -->
</div>
</div>
<div>----------------------------------------------------<br></div>
<!-- < computed 속성 vs watch 속성 > -->
<div id="app-2">
<p> {{ fullName }} </p>
<p> input below line in console and watch logs</p>
<p> app2.firstName = 'Tom'; </p>
<p> app2.lastName = 'Cruise'; </p>
</div>
<div>----------------------------------------------------<br></div>
<!-- < watch 속성 활용 > -->
<div id="app-3">
<p>
yes/no 질문을 물어보세요:
<input v-model="question">
</p>
<p>{{ answer }}</p>
</div>
<div>----------------------------------------------------<br></div>
- script -
// < computed 속성 vs methods 속성 >
//앞에서 콧수염 방식 안에 간단한 JavaScript 표현식을 넣을 수 있다고 했습니다.
//예) {{ numVal * 2 }} / {{ boolVal ? boolVal : false }}
//근데 표현식이긴 한데 너무 길어지면 가독성도 떨어지고 표현이 복잡해집니다.
//예) {{ msg.split('').reverse().join('') }}
//예시기는 하지만 벌써 함수가 세 개나 들어갔는데, 이게 과연 이렇게 쓰는 게 맞는 것일까?
//직관적이지 않고, 여러 곳에서 불러야 한다면 유지보수도 어려워집니다.
//이럴 때 쓰면 좋은 기술이 바로 computed 속성입니다.
//복잡할수록 콧수염 방식 안에 표현식으로 쓰지 말고 computed를 써야 합니다.
//methods에 함수를 정의한 뒤 불러다 쓰는 방식으로도 똑같은 기능을 구현할 수 있지만 차이점이 있습니다.
//reversedByComputed (computed에서 불러다 씀)는 계산한 결과 값을 들고 있다가 호출되면 그 값을 넘겨줍니다.
//reversedByComputed는 여러 번 불러도 가지고 있던 값을 그대로 돌려주기 때문에 함수를 실행하는 횟수는 한 번뿐입니다.
//reversedByComputed는 의존하고 있는 값, msg가 바뀔 때만 함수를 새로 실행해서 결과 값을 새로 들고 있습니다.
//reversedByMethods (methods에서 불러다 씀)는 10번 부르면 10번 다 일일이 함수를 실행해 보고 그 결과를 되돌려줍니다.
//reversedByMethods 를 쓰면 꼭 필요하지 않은 경우에도 getter함수를 여러 번 부르게 됩니다.
//로직이 복잡해질수록 computed에서 불러다 쓰는지, 아니면 methods에서 불러다 쓰는지에 따라 큰 차이를 만들게 됩니다.
//물론 굳이 캐싱을 가져다 쓰지 않지 않기를 원한다면 일부러 methods를 불러다 쓰는 게 더 좋습니다.
//캐싱을 가져다 쓰지 않을 만한 경우는 예를 들어서 같은 경우입니다.
//computed를 사용한다면 Date.now()는 다른 값을 참조하고 있지 않기 때문에 내부적으로 그 값이 바뀌더라도 함수를 새로 실행하지 않고 처음에 실행했던 결과 값을 그대로 들고 있다가 되돌려주게 됩니다.
//시간을 엄청 민감하게 다루어야 하는 경우에는 부를 때마다 새로 실행하도록 methods에서 부르면 좋습니다.
//단, 의존하고 있는 값, data 속성, 여기서는 msg 가 바뀔 때마다 결과값도 같이 갱신해주는 기능은 computed 에서 부르든 methods 에서 부르든 똑같습니다.
var app1 = new Vue({
el: '#app-1',
data: {
msg: 'This is HELLO WORLD~!!!'
},
methods: {
reversedByMethods : function() {
return this.msg.split('').reverse().join('');
}
},
computed : {
reversedByComputed: function(){
return this.msg.split('').reverse().join('');
}
}
})
app1.msg = 'try input below line in console';
// < computed 속성 vs watch 속성 >
//위에서 봤던 computed 속성은 소프트웨어 공학에서 이야기하는 '선언형 프로그래밍' 방식이라고 합니다.
//반면 아래에서 보는 watch 속성은 '명령형 프로그래밍'이라고 합니다.
//computed 속성 같은 선언형 프로그래밍 방식은 계산해야 하는 목표 데이터를 정의하는 방식입니다.
//watch 속성과 같은 명령형 프로그래밍 방식은 감시할 데이터를 지정하고 그 데이터가 바뀌면 이런 함수를 실행하라는 방식입니다.
//(역자 주: 일반적으로 선언형 프로그래밍이 명령형 프로그래밍보다 코드 반복이 적은 등 우수하다고 평가하는 경향이 있음.)
var app2 = new Vue({
el: '#app-2',
data: {
firstName: 'say',
lastName: 'park',
fullName:'say park'
},
watch: {
firstName: function(val) {
console.log('passing throug watch > firstName');
this.fullName = val + ' ' + this.lastName;
},
lastName: function(val) {
console.log('passing throug watch > LastName');
this.fullName = this.firstName + ' ' + val;
}
}
})
// < watch 속성 활용 >
//watch 속성 안에 question을 선언합니다. 즉, question 값을 감시하기로 합니다.
//question 값이 바뀔 때마다 선언해 놓은 function() 을 실행합니다.
//여기서는 data 속성의 answer 값을 '입력을 기다리는 중...'로 바꾸고 this.debouncedGetAnswer()를 실행합니다. 그게 question 값이 바뀔 때마다 실행할 함수입니다.
//created 후크로 this.debouncedGetAnswer 안에 함수를 넣어 줍니다.
//crated 후크에서는 초기값이 이미 다 들어간 뒤이기 때문에 methods 에 정의된 값들을 꺼내다 쓸 수 있습니다.
//원래는 ajax 같은 거 써서 서버까지 다녀오는 처리가 있습니다. 이유는 watch 속성을 비동기식 처리에 사용하면 좋다는 걸 보여주기 위해서입니다. 여기서는 그냥 setTimeout 함수로 대체하겠습니다.
var app3 = new Vue({
el: '#app-3',
data: {
question: '',
answer: '질문을 하기 전까지는 대답할 수 없습니다.'
},
watch: {
// data 속성의 question 값이 변경될 때마다 이 기능이 실행됩니다.
question: function (newQuestion) {
this.answer = '입력을 기다리는 중...'
this.debouncedGetAnswer()
}
},
created: function () {
this.debouncedGetAnswer = this.getAnswer
},
methods: {
getAnswer: function () {
if (this.question.indexOf('?') === -1) {
this.answer = '질문에는 일반적으로 물음표가 포함 됩니다. ;-)'
return
}
this.answer = '생각중...'
setTimeout(() => {this.answer = "hello " + this.question;}, 3000);
}
}
})
참고자료
https://kr.vuejs.org/v2/guide/computed.html
- 220421
반응형
'Vue JS' 카테고리의 다른 글
Vue.js 시작하기 06 - 조건부 렌더링, v-if, v-if-else, v-show (0) | 2022.05.01 |
---|---|
Vue.js 시작하기 05 - 클래스와 스타일 바인딩 ( html class / 인라인 style 바인딩) (0) | 2022.04.24 |
Vue.js 시작하기 03 - 템플릿 문법 (보간법, 디렉티브, 동적 전달 인자 넘기기) (0) | 2022.04.24 |
Vue.js 시작하기 02 -인스턴스 (데이터, 메소드, 라이프 사이클) (0) | 2022.04.24 |
Vue.js 시작하기 01 - 기초 문법 ( 선언적 렌더링, 조건문과 반복문, 사용자 입력 핸들링, 컴포넌트 등) (0) | 2022.04.24 |