Vue:ゼロから始めるWebアプリ開発 第6回 リストのフィルター

こんにちはTakahiRoyteです!

バイツァダストのループから中々抜けられず更新が空いてしまいました!
(その結果が吉良がたこ焼き食べる平行世界なのです)
気を取り直して、今回は表示するTodoの切り替え機能を作成していきましょう。

まずは前回の状態を確認します。

■DEMO & サンプルソース(前回の状態)

読込、保存、追加、すべてちゃんと動いていますね。
残るは左下の All | Working | Completed の切り替えのみです。

computed(算出)プロパティとはなんだ


computedプロパティはVueインスタンスのdataプロパティと似ています。違いとして、Vueインスタンス内で直接computedプロパティの値変更を行うことはありません。computedプロパティはdataプロパティがインスタンス内もしくは紐付けられたフォーム上でリアクティブに変更された場合に算出され直す、という動きをします。説明だけでも難しいので例を見てみましょう。

const app = new Vue({
el: '#app',
data: {
myNumber: 10
},
computed: {
doubleNumber: function() {
return this.myNumber * 2;
}
},
methods: {
addOne: function () {
this.myNumber++;
}
}
})

上の例ではdatamyNumberというプロパティが10として定義されています。computedにはdoubleNumberというプロパティがmyNumberを2倍にして返す関数が定義されています。methodsにはaddOneというmyNumberに1を足す関数が定義されています。

■DEMO & サンプルソース

画面が表示されると左の入力ボックスにはmyNumberの10、その右側にはdoubleNumberの結果である20が表示されます。入力ボックス内の値を変更するとそれに伴いdoubleNumberの内容も更新されます。これはフォーム上のリアクティブな更新です。

また、add 1ボタンをクリックするとmethods内のaddOneメソッドが実行され、myNumberに1が足されると同時にdoubleNumberの値も更新されます。こちらはVueインスタンスのメソッドからの更新です。

シンプルに言ってしまえば、Vueインスタンス内のdataの値が変わるとそれに合わせて動的に算出される値がcomputedです。メソッドなどを使わずとも複雑なロジックにより値を動的に算出させられるのでなかなか便利です。

今回は、今までのdataにすべてのTodoリストをデータとして持たせ、画面にはcomputedを利用してフィルターされたリストを表示するという使い方で実装を進めます。

Computed を使ってみる


早速computedを使ってみましょう。フィルターされた状態のリストを表示したいので、リストの名前はfilteredTodosとします。まずHTML側から修正してみます。今まではv-for="todo in todos"というタグでtodosの中身を表示していました。今回はfilteredTodosに修正するので、下記の通りに直します。

<!-- ★todo in todosからfitleredTodosに修正 -->
<div>{{ todo.title }}</div>

直した直後は結果画面は正常に表示されません。なぜならfilteredTodosはまだ定義してあげていないからです。早速filteredTodosをJavaScript側のVueインスタンスに定義していきましょう。定義する際にはひとまず、todosを返すだけのシンプルな値にしてみます。インスタンス内の変数を指定する際のthisをお忘れなく!

computed: {
// ★ filteredTodosを定義し、ひとまずtodosを返す
filteredTodos: function() {
return this.todos
}
},

結果を見てみましょう。

■DEMO & サンプルソース

表示するリストをtodosからfilteredTodosに変えたにもかかわらず正常に表示されていますね!その前にフィルター機能がちゃんと働くか少し試してみませんか?例えば、filteredTodosで返す配列this.todosに対して指定した配列の一部を返す.slice(0, 1)を使ってみてください(この場合0番目の要素から1つだけ要素を取ります)。

computed: {
// ★ filteredTodosを定義し、ひとまずtodosを返す
filteredTodos: function() {
return this.todos.slice(0, 1)
}
},

今までは複数あった要素が1つだけ表示されるかと思います。todosに格納された値を変更することなくcomputed内で自由に返す値をいじれる利便性に少しずつでも気づいて頂ければ幸いです。あとはfilteredTodosが返す配列を選択したフィルターに応じて変更するだけです。あ、slice()は忘れず外しておいてくださいね。

フィルターを実装しよう


下記の3ステータスにもとづいてフィルターは返す値を切り替えます。

  • All
  • Working
  • Done

では各Todoタスクのどのデータを見てフィルターを切り替えるのでしょうか?下記がTodoリスト内の1オブジェクトです。

{
id: Date.now(),
title: 'todoする',
isDone: false
}

お気づきになった鋭い方もいらっしゃるかもしれません、そうです、タスクのisDoneを見て判断します。選択したステータスの状態と各TodoタスクのisDoneを比較し、配列に変更を加えて返却すればいけそうです。何をすれば良いかを下記にまとめます。チャレンジしてみたい方は下記のリストだけで実装に挑戦してみてください。

  1. Vueインスタンスのデータにステータス状態管理用の変数を追加する
  2. HTML上の各ステータスをクリックすると、1.のステータス状態管理の変数が書き替わるようにする
  3. ステータス状態管理の変数の値をもとにcomputed内でタスクを操作した配列を返す

できそうですか?フィルター部分が少し難しいかもしれません。私はswitch文と配列の.filter()メソッドを使って実装しました。ではサンプルコードを見てみましょう。

■DEMO & サンプルソース

todogif

Todoを追加して、チェックボックスのオンオフとフィルターの切り替えで色々試してみてください。意図したとおりフィルターがかかりますね!

ひとまずこれでTodoリストの作成は完了しました!この実装がベストではありませんし、処理やスタイルの追加など改善の余地はたくさん思います。ぜひ色々試してみてください。そして今回使った技術をベースにすれば小さなアプリケーションは意外とすぐ作れちゃったりします。このTodoリストがあなたのファーストステップになれば幸いです:)

何か質問があれば@TakahiRoyteまでDMでご連絡ください!

次回は vue-cli を使ったアプリケーションの開発方法について説明します。

記事一覧

第1回 JSの歴史とVue.jsを選んだ理由
第2回 開発環境とHello Vue.js
第3回 構造のHTMLとスタイルのCSS
第4回 JSコーディング開始
第5回 保存と読込
第6回 リストのフィルター

伊藤 貴洋 について

フルスタックエンジニア目指して勉強中。アジャイル開発の推進も担当しています。