만약 객체의 상태에 따라서 템플릿에 동적으로 표현을 해줘야할 경우 아래와 같이 한다.
<template>
<p>Has published books:</p>
<span>{{ author.books.length > 0 ? 'Yes' : 'No' }}</span>
</template>
<script setup>
const author = reactive({
name: 'John Doe',
books: [
'Vue 2 - Advanced Guide',
'Vue 3 - Basic Guide',
'Vue 4 - The Mystery'
]
})
</script>
author.books의 길이가 0 이상이면 Yes, 아니면 No를 표현 해준다.
간단한경우는 상관 없지만, 복잡하거나 양이 많아지면 template이 커진다.
따라서 이런 경우 computed를 사용하는게 좋다.
<template>
<p>Has published books:</p>
<span>{{ publishedBooksMessage }}</span>
</template>
<script setup>
const author = reactive({
name: 'John Doe',
books: [
'Vue 2 - Advanced Guide',
'Vue 3 - Basic Guide',
'Vue 4 - The Mystery'
]
})
// a computed ref
const publishedBooksMessage = computed(() => {
return author.books.length > 0 ? 'Yes' : 'No'
})
</script>
computed는 reactive의 상태를 추적해 바뀌면 바로 업데이트 해준다.
위 결과는 아래 일반 함수를 사용한것과 동일 할 것이다.
function calculateBooksMessage() {
return author.books.length > 0 ? 'Yes' : 'No'
}
차이점이라면 캐시에 차이가 있다. computed는 캐싱을 해놓고 직접적으로 값이 변화되기 전에는 더이상 실행하지 않는다. 하지만 methods는 작성한 값 이외에 다른 값이 변하게되면 그때마다 계속 함수를 실행한다.
<template>
<br><input type="text" v-model="computedName" />
<h2>methods {{ getMethod() }}</h2>
<h2>computed {{ getComputed }}</h2>
</template>
<script setup>
const computedName = ref("홍길동")
const getComputed = computed(() => {
console.log('computed!!')
})
function getMethod() {
console.log('methods!!');
}
</script>
실행한 뒤 input에 값을 입력하게되면 computeName 값이 변하게 된다. 변화하게 되면 getMethod()의 경우 계속 실행을 하지만, getComputed는 값의 차이가 없어 실행하지 않는다.
getComputed() 안에
console.log(computedName.value)
만 찍어줘도 computedName의 변화가 getComputed()에 영향을 줘 로그에 computed도 찍히는것을 볼 수 있다.
Computed는 기본적으로 get 속성이지만 set이 필요한 경우 명시해서 사용할 수 있다.
const firstName = ref('John')
const lastName = ref('Doe')
const fullName = computed({
// getter
get() {
return firstName.value + ' ' + lastName.value
},
// setter
set(newValue) {
// Note: we are using destructuring assignment syntax here.
[firstName.value, lastName.value] = newValue.split(' ')
}
})
console.log("get : " + fullName.value)
fullName.value = '홍 길동'
console.log("set : " + fullName.value)