<input type="text" v-model="name">
<button v-on:click="resetInput">Reset Input</button>
<p>Your Name: {{ name }}</p>
v-on:input
v-bind:value
v-bind:value
, v-on:input
의 축약어
- DOM Interaction, Templates & Data Binding
- Event Handling
- "Advanced" Reactivity
성을 추가하는 기능을 메서드로 구현해보자!
<h2>Events in Action</h2>
<button v-on:click=addCounter(5)>Add</button>
<button v-on:click=reduceCounter(5)>Reduce</button>
<p v-once>Starting Counter: {{ counter }}</p>
<p>Result: {{ counter }}</p>
<input type="text" v-model="name">
<button v-on:click="resetInput">Reset Input</button>
<p>Your Name: {{ outputFullname() }}</p>
methods: {
outputFullname() {
console.log('Running again...')
if (this.name === '') {
return '';
}
return this.name + ' ' + 'Lee';
},
}
이제 정상적으로 성을 뒤에 붙여주는 기능을 구현했다.
그러나 이것은 최고의 방법이 아니다.
🧐 왜 최고의 방법이 아닐까?
위에 counter 값이 변화할때도 보이진 않으나 Vue가 내부에서 이상적이지 않은 어떤 기능을 수행한다.
counter 값이 변경되면 Vue는 기본적으로 이 페이지에서 렌더링 된 페이지를 업데이트 할 위치를 찾으려고 한다. 가령 <p>Result: {{ counter }}</p>
이 부분에서 counter를 사용하고 있으므로 이 부분을 업데이트하려고 할 것이다. (이같은 자동 업데이트 기능이란 장점이 우리가 vue를 사용하는 이유이기도 하다.)
문제는 outputFullname()
과 같은 메서드를 실행하면, 페이지에 변경이 생길 때마다 메서드도 Vue에 의해 재실행된다. (만약 outputFullname() 메서드에서 counter 값이 변경이 있다면, 이 메서드가 실행되는 것이 실제로 옳은 행위일 것이다.) Vue는 메서드가 하는 일을 알 수 없기 때문에, counter 사용 여부 역시 모르고, 따라서 HTML 코드 내 모든 메서드들을 재실행한다! 😮 이는 성능 면에서 좋지 않다.
따라서, 메서드는 동적으로 계산된 값을 출력하기 위한 최선의 해결책은 아니다. 더 나은 해결책은 무엇일까?
<input type="text" v-model="name">
<button v-on:click="resetInput">Reset Input</button>
<p>Your Name: {{ fullName }}</p>
computed: {
fullName() {
console.log('Running again...');
if (this.name === '') {
return '';
}
return this.name + ' ' + 'Lee';
}
},
fullName
(⭕️)fullName()
(❌)computed 프로퍼티에 사용된 뭔가를 변경해야만 해당 객체가 작동한다.
Vue는 computed 프로퍼티의 의존성을 인식(여기선 name에 의존하고 있다)한다. computed 프로퍼티 값을 캐시에 저장하고 의존성 중 하나, 이 경우 유일한 의존성인 name 프로퍼티가 변경된 경우에만 재계산하고 재평가한다.
성능 면에서 값을 출력하는 대부분의 경우 메서드보다 연산 프로퍼티 사용이 좋다. 페이지에서 어떤 항목이 변경되든 값을 재계산하려는 경우에만 메서드를 사용한다. 그러나 대부분의 경우에 의존성이 변경되는 경우에만 재계산하길 원할텐데, 이런 경우 computed를 사용할 수 있다.
<input type="text" v-model="name">
<button v-on:click="resetInput">Reset Input</button>
<p>Your Name: {{ fullName }}</p>
watch: {
// name이 변경될때마다 watch가 재시행된다.
name(value) {
this.fullName = value + ' ' + 'Lee';
}
},
computed
와 유사하며 실제로 대신 사용할 수 있다. watch: {
name(newValue, oldValue) {...}
}
🤔 거의 computed와 차이가 없다. 왜 두가지가 구분되어 있을까?
watcher 사용의 문제점은 두 개 이상의 요소에 의존성을 가지고 있는 경우 발생한다. 이번에는 "성"과 "이름" 모두에 반응하는 기능을 구현하려고 한다.
<input type="text" v-model="name">
<input type="text" v-model="lastName">
<p>Your Name: {{ fullName }}</p>
watch: {
name(value) {
if(value === '') {
this.fullName = '';
} else {
this.fullName = value + ' ' + 'Lee';
}
},
lastName(value) {
if(value === '') {
this.fullName = '';
} else {
this.fullName = this.name + ' ' + value;
}
}
},
두 개 이상의 변수를 추적하면서 코드가 중복되는 모습을 보인다. 같은 기능을 computed
로 구현해보면 어떻게 코드가 바뀔까?
computed: {
fullname() {
if(this.name === '' || this.alstNAme === '') {
return '';
}
return this.name + ' ' + this.lastName;
}
},
훨씬 간단해진 모습을 확인 할 수 있다.
🤔 성능이 computed가 좋다면 왜 watch가 존재하는 걸까?
이 같은 기능은 watch의 핵심 기능이 아니기 때문이다.
이번엔 counter가 50을 초과하면 재설정하는 기능을 구현해보자. 이런 종류의 작업에서 watch이 유용하다.
watch: {
counter(value) {
if(value > 50) {
this.counter = 0;
}
}
},
데이터 프로퍼티를 업데이트하나 항상 업데이트해선 안되는 로직을 실행하려는 경우 computed보다 watch가 훨씬 유용할 수 있다.
또 다른 예로, "특정 데이터가 변경되면 보내는 HTTP 요청", "특정 값이 변경되면 설정하는 타이머"에도 watch가 유용할 수 있다.
🙄 음.. methods.. computed... wat.. 너무 혼란서롭고 헷갈린다...
😀 간단하게 정리해보자!
{{}}
보간법 사용등을 위함... 근데 정리를 해도 헷갈린다..ㅠㅠ
v-on:click
= @click
v-bind:value
= :value
+) v-model은 축약어가 없다.