계산된 속성을 정의하는 함수
미리 계산된 속성을 사용하여 템플릿에서 표현식을 단순하게 하고 불필요한 반복 연산을 줄임
computed 기본 예시, 적용
<body>
<div id="app">
<h2>남은 할 일</h2>
// 1번째 방법
<p>{{ restOfTodos }}</p>
// 메서드 활용방법
<p> {{ getRestofTodos() }}</p>
</div>
<script src="<https://unpkg.com/vue@3/dist/vue.global.js>"></script>
<script>
// computed 적용
const { createApp, ref, computed } = Vue
const app = createApp({
setup() {
// 할 일이 남았는지 여부에 따라 다른 메시지 출력하기
const todos = ref([
{ text: 'Vue 실습' },
{ text: '자격증 공부' },
{ text: 'TIL 작성' }
])
const restOfTodos = computed(() => {
return todos.value.length > 0 ? '아직 남았다' : '퇴근!'
})
const getRestofTodos = function () {
return todos.value.length > 0 ? '아직 남았다' : '퇴근!'
}
return {
todos,
restOfTodos,
getRestofTodos
}
}
})
app.mount('#app')
</script>
</body>
computed 속성 대신 method 로도 동일한 기능을 정의할 수 있음
- 두 가지 접근 방식은 실제로 완전히 동일
캐시(Cache)
- 데이터나 결과를 일시적으로 저장해두는 임시 저장소
- 이후에 같은 데이터나 결과를 다시 계산하지 않고 빠르게 접근할 수 있도록 함
ex. 웹 페이지의 캐시 데이터 -> 페이지 일부 데이터를 브라우저 캐시에 저장 후 같은 페이지에 다시 요청 시 모든 데이터를 다시 응답 받는 것이 아닌 캐시 된 데이터를 사용하여 더 빠르게 웹 페이지를 렌더링
computed
의존된 데이터가 변경되면 자동으로 업데이트
method
호출해야만 실행됨
💡 무조건 computed만 사용하는 것이 아니라 사용목적과 상황에 맞게 computed와 method를 적절히 조합하여 사용
const app = createApp({
setup() {
const isSeen = ref(true)
return {
isSeen,
}
}
})
<!-- if else -->
<p v-if="isSeen">true일때 보여요</p>
<p v-else>false일때 보여요</p>
<button @click="isSeen = !isSeen">토글</button>
<!-- else if -->
<div v-if="name === 'Alice'">Alice입니다</div>
<div v-else-if="name === 'Bella'">Bella입니다</div>
<div v-else-if="name === 'Cathy'">Cathy입니다</div>
<div v-else>아무도 아닙니다.</div>
HTML <template>
element
<!-- v-show -->
<div v-show="isShow">v-show</div>
v-show는
display: none
으로 렌더링은 한다!!
v-if(Cheap initial load, expensive toggle)
- 초기 조건이 false인 경우 아무 작업도 수행하지 않음
- 토글 비용이 높음
v-show(Expensive initial load, cheap toggle)
- 초기 조건에 관게 없이 항상 렌더링
- 초기 렌더링 비용이 더 높음
- 토글이 되어있는 상태에서는 싸게 먹힌다
=> 무언가를 매우 자주 전환해야 하는 경우에는 v-show를 ,
실행중에 조건이 변경되지 않는 경우에는 v-if 를 권장
alias in expression
형식의 특수 구문을 사용하여 반복되는 현재 요소에 대한 별칭(alias)을 제공배열 반복
<div v-for="(item, index) in myArr">
{{ index }} // {{item.name}}
</div>
객체 반복
<div v-for="(value, key, index) in myObj">
{{ index }} // {{key}} // {{value}}
</div>
여러 요소에 대한 v-for 적용
<!-- v-for on <template> -->
<ul>
<template v-for="item in myArr">
<li> {{ item.name }}</li>
<li> {{item.age}} </li>
<hr>
</template>
</ul>
중첩된 v-for
<!-- nested v-for -->
<ul v-for="item in myInfo">
<li v-for="friend in item.friends">
{{item.name}} - {{ friend }}
</li>
</ul>
반드시 v-for 와 key를 함께 사용한다
- 내부 컴포넌트의 상태를 일관되게 유지
- 데이터의 예측 가능한 행동을 유지(Vue 내부 동작 관련)
> 동일 요소에 함께 사용하지 않는다!!
문제상황1
<!-- [Bad] v-for with v-if -->
<ul v-for="todo in todos" v-if="!todo.isComplete" :key="todo.id">
<li>
{{todo.name}}
</li>
</ul>
해결법
1. computed를 활용해 필터링 된 목록을 반환하여 반복하도록 설정
const completeTodos = computed(() => {
return todos.value.filter((todo) => !todo.isComplete)
})
<li v-for="todo in completeTodos" :key="todo.id">
{{todo.name}}
</li>
구조
variable - 감시하는 변수
newValue - 감시하는 변수가 변화된 값 / 콜백 함수의 첫번째 인자
oldValue - 콜백 함수의 두번째 인자
const countWatch = watch(count, (newValue, oldValue) => {
console.log(`newValue: ${newValue}, oldValue: ${oldValue}`)
})
const messageWatch = watch(message, (newValue, oldValue) => {
messageLength.value = newValue.length
})
★ computed와 watch 모두 의존(감시)하는 원본 데이터를 직접 변경하지 않음!!
onMounted = 앱이 템플릿에 마운트되었을때(연결되었을때) 출력됨
onMounted(() => {
console.log('mounted')
})
onupdated = 업데이트 되엇을 때!!
computed에서 reverse() 및 sort() 사용시 원본 배열을 변경하기 때문에 복사본을 만들어서 진행해야 함 |
---|
배열의 인덱스를 v-for의 key로 사용하지 말 것 |
---|