15
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Vue3 チュートリアル 3 ToDoアプリの実装練習

Last updated at Posted at 2022-07-26

前回学んだVue3の基本を元に、Vue3でToDoアプリを実装していきましょう。

ゴール

  • 前回学んだ内容でVue3のToDoアプリを実装する
  • できるだけ自分の力で実装を進める

ToDoアプリ作成

今回のToDoアプリ作成では、こちらからテンプレート部分は提供します。
そこにVueでインタラクティブな処理を実装していきます。

準備

前回作ったApp.vueファイルは参考にすると思うので、Tutorial2.vueなどに名前を変えて保存しましょう。
Git管理下のファイルのファイル名を変える時は、VSCode上から実施してください。
エクスプローラーやコマンドラインからリネームするとGitの対象から外れてしまいます。
(本来はGitのコマンドを使ってやるところをVSCodeが裏でいい感じに実施してくれています)
その上で新たなApp.vueを作って以下のコードをコピーしてください。

App.vue
<script>
export default {
  data() {
    return {}
  },
  methods: {},
}
</script>

<template>
  <h1>My ToDo App</h1>
  <input type="text" /><button>追加</button><button>完了済みを削除する</button>
  <ul>
    <li>
      <input type="checkbox" checked /><span class="todo-done"
        >Vueをマスターする</span
      >
    </li>
    <li><input type="checkbox" /><span>牛乳を買う</span></li>
    <li><input type="checkbox" /><span>家賃を払う</span></li>
  </ul>
</template>

<style>
body {
  background-color: #eee;
}

.todo-done {
  text-decoration: line-through;
}
</style>

画面イメージは以下の通りです:
image.png

要件

いくつかの要件を示します。
実装していく順番は自由ですが、上から下がやりやすいと思います。

  • ToDoデータは完了の状態と文字列を保持しリストで表示する
  • 初期表示でデータが何もない時、リストの位置に「ToDoがまだありません!」と表示する
  • フォームに文字を入力し、追加ボタンを押すと文字列を元にToDoリストに追加される
  • ToDoに追加したタイミングでフォームの文字列はクリアされる
  • フォームに文字が未入力時に追加ボタンを押しても、アラートが表示されリストに追加されない
  • ToDo毎のチェックボックスのオンオフで文字列に完了済みのラインの切り替えができる
  • 完了済みを削除するボタンを押すとチェックボックスがオンになっているToDoが削除される

以上を可能な限り独力で前回のコードを参考にしながら実装してみてください。
行き詰まった場合は、上の順番通り各要件ごとにヒントのテキストとコードがあるので参考にしてみてください。

  1. できるだけヒントを見ずに実装
  2. 詰まったらヒントを見ながら実装
  3. 分からなくなったらサンプルコードを参考に実装

ヒント集

以下からはヒント集になります。
イメージとしては以下の順番で取り組んでみてもらえれば嬉しいです。

  1. できるだけヒントを見ずに実装
  2. 詰まったらヒントを見ながら実装
  3. 分からなくなったらサンプルコードを参考に実装

ToDoデータは完了の状態と文字列を保持しリストで表示する

ヒント

  • サンプルコードを参考にdataに仮のデータtodosを作ってみる
  • データはオブジェクトの配列で、オブジェクトは完了状態のbooleanとToDoの文字列を持つ
  • テンプレートではv-forを使って仮データを配列で表示してみる
  • v-forを適用するのはli要素、v-for="todo in todos"
  • 文字列を表示するのは{{ }}
  • この時点ではチェックボックスや完了済みラインは気にしない

コード

script
  data() {
    return {
      todos: [
        {
          isDone: true,
          text: 'Vueをマスターする'
        },
        {
          isDone: false,
          text: '牛乳を買う'
        },
        {
          isDone: false,
          text: '家賃を払う'
        },
      ],
    }
  }
template
    <li v-for="todo in todos">
      <input type="checkbox" /><span>{{ todo.text }}</span>
    </li>

ToDoデータが何もない状態の時、リストの位置に「ToDoがまだありません!」と表示する

ヒント

  • メッセージ表示用のHMTL要素を追加する
  • v-ifv-elseを使う
  • v-ifの条件はToDoデータ配列の長さが0の場合、todos.length === 0
  • 最初はToDoデータがある状態で実装してみる
  • 次にToDoデータを空の配列にして表示が正しくなされるか見てみる

コード

script
  data() {
    return {
      todos: [],
    }
  },
template
  <p v-if="todos.length === 0">ToDoがまだありません!</p>
  <ul v-else>
    <li v-for="todo in todos">
      <input type="checkbox" /><span>{{ todo.text }}</span>
    </li>
  </ul>

フォームに文字を入力し、追加ボタンを押すと文字列を元にToDoリストに追加される

ヒント

  • フォームのinput要素の値を管理するデータをdata内に持つ
  • v-modelを使いinput要素とdataの値をバインディングする
  • methodsaddTodoを追加する
  • データのToDoの配列にインプットとバインディングされている文字列を元にオブジェクトをpushする
  • ToDoのデータはオブジェクトで、完了状態と文字列をプロパティとして持つこと
  • Vueのインスタンス内でオプションのプロパティを利用する時はthis.を忘れないこと!

コード

script
export default {
  data() {
    return {
      newTodoText: '',
      todos: [],
    }
  },
  methods: {
    addTodo() {
      this.todos.push({
        isDone: false,
        text: this.newTodoText,
      })
    },
  },
}
template
<input type="text" v-model="newTodoText" /><button @click="addTodo">追加</button>

ToDoに追加したタイミングでフォームの文字列はクリアされる

ヒント

  • methodsに追加したToDoを追加するメソッドに修正を加える
  • フォームとバインディングされているテキストをクリアする
  • data内の特定の値をメソッド内で利用する時はthis.を忘れないこと!

コード

script
    addTodo() {
      this.todos.push({
        isDone: false,
        text: this.newTodoText,
      })
      this.newTodoText = ''
    }

フォームに文字が未入力時に追加ボタンを押しても、アラートが表示されリストに追加されない

  • methodsに追加したToDoを追加するメソッドに修正を加える
  • アラートはWeb標準で提供されているalertメソッドを使ってOK
  • 処理を抜け出すよう、分岐を設けreturnで処理を終える

コード

script
if(this.newTodoText === '') {
  alert('文字を入力してください')
  return 
}

// あるいは1行で簡潔に
if (!this.newTodoText) return alert('文字を入力してください')

ToDo毎のチェックボックスのオンオフで文字列に完了済みのラインの切り替えができる

ヒント

  • 文字の装飾用のCSSはtodo-doneクラスとして<style>に用意されている
  • classv-bindする、v-bindの略記法は:xxxxx
  • classのバインディングの時はオブジェクトを渡し、キーをクラス名、値を真偽値(boolean)
  • クラス名にハイフンが入っている場合はオブジェクトのキー名はクォーテーションマークで囲む('class-name')
  • バインドするオブジェクトはこんな感じ、{'class-name': booleanValue }

コード

template
      <input type="checkbox" v-model="todo.isDone" /><span
        :class="{ 'todo-done': todo.isDone }"
        >{{ todo.text }}</span
      >

完了済みを削除するボタンを押すとチェックボックスがオンになっているToDoが削除される

ヒント

  • ボタンに対応する新たなメソッドをmethodsに追加する、名前はclearDoneTodosなど
  • Todo配列を、完了状態で未完了のものだけにフィルターした配列に置き換える

コード

script
    clearDoneTodos() {
      this.todos = this.todos.filter((todo) => !todo.isDone)
    },

まとめ

実装作業はどうでしたでしょうか?
ヒントのテキストやコードを見ながらでも、実装できてコードの理解が進んでいれば順調です!
最後にサンプルとしての実装コード全体を共有するので、ご自身のコードと見比べてみてください。
必要に応じて修正してもらって、納得した形になったらGitにコミットしておきましょう。

App.vue
<script>
export default {
  data() {
    return {
      newTodoText: '',
      todos: [
        // { isDone: false, text: 'ToDoの文字列'}
      ],
    }
  },
  methods: {
    addTodo() {
      if (!this.newTodoText) return alert('文字を入力してください')
      this.todos.push({
        isDone: false,
        text: this.newTodoText,
      })
      this.newTodoText = ''
    },
    clearDoneTodos() {
      this.todos = this.todos.filter((todo) => !todo.isDone)
    },
  },
}
</script>

<template>
  <h1>My ToDo App</h1>
  <input type="text" v-model="newTodoText" /><button @click="addTodo">
    追加</button
  ><button @click="clearDoneTodos">完了済みを削除する</button>
  <p v-if="todos.length === 0">ToDoがまだありません!</p>
  <ul v-else>
    <li v-for="todo in todos">
      <input type="checkbox" v-model="todo.isDone" /><span
        :class="{ 'todo-done': todo.isDone }"
        >{{ todo.text }}</span
      >
    </li>
  </ul>
</template>

<style>
body {
  background-color: #eee;
}

.todo-done {
  text-decoration: line-through;
}
</style>

次回はToDoアプリをコンポーネントに分割して、再利用性を高めながら可読性もあげていきます。

お疲れ様でした。

15
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
15
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?