computed
vue instance가 가진 options 중 하나
computed 객체에 정의한 함수를 페이지가 최초 렌더링 시 호출하여 계산
계산 결과가 변하기 전까지 그 저장된 값을 그대로 사용한다.
<div id="app">
<h1>data_01 : {{ number1 }}</h1>
<h1>data_02 : {{ number2 }}</h1>
<hr>
<h1>add_method : {{ add_method() }}</h1>
<h1>add_method : {{ add_method() }}</h1>
<h1>add_method : {{ add_method() }}</h1>
<hr>
<h1>add_computed : {{ add_computed }}</h1>
<h1>add_computed : {{ add_computed }}</h1>
<h1>add_computed : {{ add_computed }}</h1>
<hr>
<button v-on:click="dataChange">Change Data</button>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
number1: 100,
number2: 100
},
computed: {
add_computed: function () {
console.log('computed 실행됨!')
return this.number1 + this.number2
}
},
methods: {
add_method: function () {
console.log('method 실행됨!')
return this.number1 + this.number2
},
dataChange: function () {
this.number1 = 200
this.number2 = 300
}
}
})
</script>
메서드는 method()으로 실행하고 computed는 괄호 없이 실행했다.
세번씩 작성해서 실행했지만, method는 계속해서 3번 실행되는 반면, computed는 값이 변화하지 않았기 때문에 1번만 실행된다.
method, computed 비교
method
- 호출 될 때마다 함수를 실행
- 같은 결과여도 매번 새롭게 실행하여 계산한다.
- 사용 시 ()가 붙는다.
computed
- 함수의 종속대상 변화에 따라 계산 여부 결정된다.
- 종속 대상(결과에 영향을 미치는 값)이 변하지 않으면 항상 저장된 값을 반환
- 호출하는 것이 아니라, 계산된 값으로서 사용되기 때문에 ()가 붙지 않는다.
watch
<div id="app">
<h3>Increase number</h3>
<p>{{ number }}</p>
<button @click="number++">+</button>
<hr>
<h3>Change name</h3>
<p>{{ name }}</p>
<input type="text" v-model="name">
<hr>
<h3>push myObj</h3>
<p>{{ myObj }}</p>
<button @click="itemChange">change Item</button>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
number: 0,
name: '',
myObj: {completed: true}
},
methods: {
nameChange: function () {
console.log('name is changed')
},
itemChange: function () {
this.myObj.completed = !this.myObj.completed
}
},
watch: {
number: function (val, oldVal) {
console.log(val, oldVal)
},
name: {
handler: 'nameChange'
},
myObj: {
handler: function (val) {
console.log(val)
},
deep: true
},
}
})
</script>
watch는 특정 데이터의 변화를 감지한다.
watch: {
number: function (val, oldVal) {
console.log(val, oldVal)
},
watch 객체를 정의하여 감시할 대상 data를 지정한다. data가 변할시에 실행할 함수를 정의한다.
data가 변하면 함수가 실행된다. 함수의 첫번째 인자는 변동 후 data, 두번째 인자는 변동 전 data이다.
number를 감시하며, number가 변하면 변동후 data, 변동전 data를 출력하는 함수를 실행한다.
watch: {
name: {
handler: 'nameChange'
}
}
실햄 함수를 vue method로 대체 가능하다.
감시 대상 data의 이름으로 객체를 생성하고 실행하고자 하는 method를 handler에 문자열 형태로 할당한다.
name이 변경되면 nameChange 메서드가 실행된다.
watch: {
myObj: {
handler: function (val) {
console.log(val)
},
deep: true
},
}
array, object 같이 [], {} 안에 있는 요소의 변경을 감지하기 위해서는 deep : true 속성을 추가하면 된다.
<div id="app">
<h3>Increase number</h3>
<p>{{ number }}</p>
<button @click="number++">+</button>
<hr>
<h3>Change name</h3>
<p>{{ name }}</p>
<input type="text" v-model="name">
<hr>
<h3>push myObj</h3>
<p>{{ myObj }}</p>
<button @click="itemChange">change Item</button>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
number: 0,
name: '',
myObj: {completed: true}
},
methods: {
nameChange: function () {
console.log('name is changed')
},
itemChange: function () {
this.myObj.completed = !this.myObj.completed
}
},
watch: {
number: function (val, oldVal) {
console.log(val, oldVal)
},
name: {
handler: 'nameChange'
},
myObj: {
handler: function (val) {
console.log(val)
},
deep: true
},
}
})
</script>
computed, watch 비교
데이터 변경을 관찰하고 이에 반응하는 일반적인 방법은 watch 속성이다. 그러나 명령형 watch 콜백보다 computed 속성을 쓰는 것이 더 나은 경우도 많다. computed로 구현가능한 것이라면 watch가 아니라 computed로 구현하는것이 대게의 경우 옳다.
<div id="demo">{{ fullName }}</div>
const vm = Vue.createApp({
data() {
return {
firstName: 'Foo',
lastName: 'Bar',
fullName: 'Foo Bar'
}
},
watch: {
firstName(val) {
this.fullName = val + ' ' + this.lastName
},
lastName(val) {
this.fullName = this.firstName + ' ' + val
}
}
}).mount('#demo')
위 코드는 watch를 사용한 명령형이고 코드가 반복된다.
const vm = Vue.createApp({
data() {
return {
firstName: 'Foo',
lastName: 'Bar'
}
},
computed: {
fullName() {
return this.firstName + ' ' + this.lastName
}
}
}).mount('#demo')
computed를 이용한 코드가 더 간편한 경우이다.
filters
<body>
<div id="app">
<p>{{ numbers }}</p>
<p>{{ numbers | getOddNums }}</p>
<p>{{ numbers | getOddNums | getUnderTenNums }}</p>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
numbers: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15],
},
filters: {
getOddNums: function (nums) {
const oddNums = nums.filter((num) => {
return num % 2
})
return oddNums
},
getUnderTenNums: function (nums) {
const underTen = nums.filter((num) => {
return num < 10
})
return underTen
}
}
})
</script>
텍스트 형식화를 적용할 수 있는 필터
interpolation 혹은 v-bind를 이용할 때 사용 가능하다.
필터는 자바스크립트 표현식 마지막에 | 파이프와 함께 추가되어야 한다.
chaining하여 이어서 사용할 수 있다.
'Front-end > Vue.js' 카테고리의 다른 글
데이터 흐름 : pass props / emit event (0) | 2022.11.02 |
---|---|
Vue CLI / Module / Vue 프로젝트, 컴포넌트 생성 (0) | 2022.11.02 |
Template Syntax - text interpolation, directives(v-text, v-html, v-show, v-if, v-bind, v-on, v-model) (0) | 2022.10.31 |
Front-end Framework - Vue.js / MVVN 디자인 패턴 / el, data, methods (0) | 2022.10.31 |
SPA, CSR, SSR (0) | 2022.10.31 |