목표
하드코딩으로 그려지고 있는 List 를 State 기반으로 변경합니다.
실습
state 준비
준비 단계에서 살펴봤던것처럼 List 에 대한 정보는 App.vue
가 가지고 있도록 하겠습니다.
아래와 같이 list 를 구성하기 위한 state 를 추가합니다.
// App.vue
export default {
...,
data() {
return {
todos: [
{
id: new Date(),
text: "Vue 공부하기",
isDone: true
},
{
id: new Date() + 1,
text: "치킨 먹기",
isDone: false
}
]
};
}
};
</script>
id: 클라이언트에서 고유한 값을 나타낼 수 있는 수단으로 date 를 이용하였습니다.
isDone: 일이 마무리되었는지 판단 할 수 있는 값 입니다.
props 로 넘겨주기
리스트를 그리는 쪽은 App.vue가 아닌 Todo.vue 이기 때문에 props 로 todos 를 넘기겠습니다.
todos 라는 이름으로 todos state 를 넘겨줬습니다.
// App.vue
<template>
<div id="app">
<section class="todoapp">
<Header/>
<Todo :todos="todos"/>
<Footer/>
</section>
</div>
</template>
Todo.vue 에서는 App.vue 에서 넘겨준 값을 props 로 받을 수 있도록 아래 코드를 추가해줍니다.
// components/Todo.vue
<script>
export default {
props: {
todos: { type: Array, default: () => [] }
}
};
</script>
받은 props 와 v-for 를 이용하여 list 를 그려줍니다.
// components/Todo.vue
<template>
<section class="main">
<ul class="todo-list">
<li class="todo" v-for="({ id, text, isDone }, idx) in todos" :key="idx">
<div class="view">
<input class="toggle" type="checkbox">
<label>{{ text }}</label>
<button class="destroy"></button>
</div>
<input class="edit" type="text">
</li>
</ul>
</section>
</template>
{id, text, isDone} 같이 풀어서 받는 문법에 익숙하지 않다면 해체할당자 를 참고해주세요
우리가 추가한 2가지의 todo list 를 볼 수 있습니다.
condition 에 따른 class 처리
todo 에는 isDone 이라는 값이 있습니다. 이 값에 따라서 todo 의 스타일이 조금 달라져야합니다.
// components/Todo.vue
<template>
<section class="main">
<ul class="todo-list">
<li
:class="{todo: true, completed: isDone }"
v-for="({ id, text, isDone }, idx) in todos"
:key="idx"
>
<div class="view">
<input class="toggle" type="checkbox">
<label>{{ text }}</label>
<button class="destroy"></button>
</div>
<input class="edit" type="text">
</li>
</ul>
</section>
</template>
isDone 값에 따라서 completed 라는 class 를 binding 해줘야합니다.
checked 속성도 isDone 에 따라서 제어되어야 합니다.
// components/Todo.vue
<template>
<section class="main">
<ul class="todo-list">
<li
:class="{todo: true, completed: isDone }"
v-for="({ id, text, isDone }, idx) in todos"
:key="idx"
>
<div class="view">
<input class="toggle" type="checkbox" :checked="isDone">
<label>{{ text }}</label>
<button class="destroy"></button>
</div>
<input class="edit" type="text">
</li>
</ul>
</section>
</template>