10. Todo - Read

간단한 Todo App 을 만들어봅니다.

목표

하드코딩으로 그려지고 있는 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 를 이용하였습니다.

  • text: todo 의 내용

  • 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>

Last updated