할 일이 남았는지 여부에 따라 다른 메시지를 출력하기
const todos = ref([
{text : 'Vue 실습'},
{text : '자격증 공부'},
{text : 'TIL 작성'}
])
<h2> 남은 할일 </h2>
<p>{{ todos.length > 0 ? '아직 남았다' : '퇴근 !'}}</p>
computed 적용
반응형 데이터를 포함하는 복잡한 로직의 경우 computed를 활용하여 미리 값을 계산하여 계산된 값을 사용
<script>
const { createApp, ref, computed } = Vue;
const restOfTodos = computed(() => {
return todos.value.length > 0 ? "아직 남았다" : "퇴근!";
});
</script>
<h2>남은 할 일</h2>
<p>{{ restOfTodos }}</p>
const restOfTodos = computed(() => {
return todos.value.length > 0 ? "아직 남았다" : "퇴근!";
});
computed 속성 대신 method로도 동일한 기능을 정의할 수 있음
const getRestOfTodos = function(){
return todos.value.length > 0 ? '아직 남았다' : '퇴근!'
}
<p>{{ getRestOfTodos() }}</p>
computed
method
무조건 computed만 사용하는 것이 아니라 사용 목적과 상황에 맞게 computed와 method를 적절히 조합하여 사용
표현식 값의 true/false를 기반으로 요소를 조건부로 렌더링
v-else directive를 사용하여 v-if에 대한 else 블록을 나타낼 수 있음
<script>
const isSeen = ref(true);
</script>
<p v-if="isSeen">true일때 보여요</p>
<p v-else>false일때 보여요</p>
<button @click="isSeen = !isSeen">토글</button>
v-else-if directive를 사용하여 v-if에 대한 else if 블록을 나타낼 수 있음
<script>
const name = ref("Cathy");
</script>
<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요소에 v-if를 사용하여 하나 이상의 요소에 대해 적용할 수 있음
<template v-if="name === 'Cathy'">
<div>Cathy입니다</div>
<div>나이는 30살입니다.</div>
</template>
<template> elementconst isShow = ref(false)
<div v-show="isShow">v-show</div>v-if
v-show
콘텐츠를 매우 자주 전환해야 하는 경우에는 v-show를, 실행 중에 조건이 변경되지 않는 경우에는 v-if를 권장
<div v-for="item in items">{{ item.text }}</div><div v-for="(item, index) in arr"></div>
<div v-for="value in object"></div>
<div v-for="(value, key) in object"></div>
<div v-for="(value, key, index) in object"></div>const myArr = ref([ { name: 'Alice', age: 20 }, { name: 'Bella', age: 21 } ])
<div v-for="(item, index) in myArr">{{ index }} / {{ item }}</div>
const myobj = ref([ name:'Cathy', age:30 ])
<div v-for="(value, key, index) in myObj">
{{ index }} / {{ key }} / {{ value }}
</div>
<ul>
<template v-for="item in myArr">
<li>{{ item.name }}</li>
<li>{{ ite.age }}</li>
<hr />
</template>
</ul><script>
const myInfo = ref([
{ name: "Alice", age: 20, friends: ["Bella", "Cathy", "Dan"] },
{ name: "Bella", age: 21, friends: ["Alice", "Cathy"] },
]);
</script>
<ul v-for="item in myInfo">
<li v-for="friend in item.friends">{{ item.name }} - {{ friend }}</li>
</ul>
반드시 v-for와 key를 함께 사용한다
key는 반드시 각 요소에 대한 고유한 값을 나타낼 수 있는 식별자여야 함
let id = 0 const items = ref([ {id:id++, name:'Alice'}, {id: id++,
name:'Bella'} ])
<div v-for="item in items" :key="item.id"></div>
todo 데이터 중 이미 처리한 (isComplete === true ) todo만 출력하기
let id = 0;
const todos = ref([
{ id: id++, name: "복습", isComplete: true },
{ id: id++, name: "예습", isComplete: false },
{ id: id++, name: "저녁식사", isComplete: true },
{ id: id++, name: "노래방", isComplete: false },
]);
v-if가 더 높은 우선순위를 가지므로 v-for 범위의 todo데이터를 v-if에서 사용할 수 없음
<ul>
<li v-for="todo in todos" v-if="!todo.isComplete" : key="todo.id">
{{ todo.name }}
</li>
</ul>
<template>요소 활용<script>
const completeTodos = computed(() => {
return todos.value.filter((todo) => !todo.isComplete);
});
</script>
<ul>
<li v-for="todo in completeTodos" :key="todo.id">{{ todo.name }}</li>
</ul>
<ul>
<template v-for="todo in todos" :key="todo.id">
<li v-if="!todo.isComplete">{{ todo.name }}</li>
</template>
</ul>
watch(source, (newValue, oldValue) => {
// do something
});
<button @click="count++">Add 1</button>
<p>Count : {{ count }}</p>
<script>
const count = ref(0);
watch(count, (newValue, oldValue) => {
console.log(`newValue: ${newValue}, oldValue:${oldValue}`);
});
</script>
감시하는 변수에 변화가 생겼을 때 연관 데이터 업데이트 하기
<input v-model="message" />
<p>Message length: {{ messageLength }}</p>
<script>
const message = ref("");
const messageLength = ref(0);
watch(message, (newValue) => {
messageLength.value = newValue.length;
});
</script>
감시하는 변수에 변화가 생겼을 때 연관 데이터 업데이트 하기
| -- | Computed | Watchers |
|---|---|---|
| 공통점 | 데이터 변화를 감지하고 처리 | 데이터 변화를 감지하고 처리 |
| 동작 | 의존하는 데이터 속성의 계산된 값을 반환 | 특정 데이터 속성의 변화를 감시하고 작업을 수행(side-effects) |
| 사용 목적 | 계산한 값을 캐싱하여 재사용 중복 계산 방지 | 데이터 변화에 따른 특정 작업을 수행 |
| 사용 예시 | 연산 된 길이, 필터링 된 목록 계산 등 | DOM 변경, 다른 비동기 작업 수행, 외부 API와 연동 등 |
Vue 컴포넌트 인스턴스가 초기 렌더링 및 DOM요소 생성이 완료된 후 특정 로직 수행하기
const { create APP, ref, onMounted } = Vue setup() { onMounted(() => {
console.log('mounted') }) }
반응형 데이터의 변경으로 인해 컴포넌트의 DOM이 업데이트된 후 특정 로직을 수행하기
<button @click="count++">Add 1</button>
<p>Count: {{ count }}</p>
<p>{{ message }}</p>
<script>
const { createApp, ref, onMounted, onUpdated } = Vue;
const count = ref(0);
const message = ref(null);
onUpdated(() => {
message.value = "updated!";
});
</script>
반응형 데이터의 변경으로 인해 컴포넌트의 DOM이 업데이트 된 후 특정 로직을 수행하기
Vue의 스타일 가이드 규칙은 우선운위에 따라 4가지 범주
우선순위 A : 필수
우선순위 B : 적극 권장
우선순위 C : 권장
우선순위 D : 주의 필요
작재적 위험 특성을 고려함
원본 데이터를 수정하거나 교체하지 않고 필터링하거나 정렬된 새로운 데이터를 표시하는 방법
computed 활용
<script>
const numbers = ref([1, 2, 3, 4, 5]);
const evenNumbers = computed(() => {
return numbers.value.filter((number) => number % 2 === 0);
});
</script>
<li v-for="num in evenNumbers">{{ num }}</li>
method 활용
<script>
const numberSets = ref([
[1, 2, 3, 4, 5],
[6, 7, 8, 9, 10],
]);
const evenNumbers = function (numbers) {
return numers.filter((number) => number % 2 === 0);
};
</script>
<ul v-for="numbers in numberSets">
<li v-for="num in evenNumbers(numbers)">{{ num }}</li>
</ul>