Vue:ゼロから始めるWebアプリ開発 第5回 保存と読込

こんにちは、TakahiRoyteです!前回の続きで、Todoアプリの保存と読込の実装していきましょう。まず前回の状態を見てみます。

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

追加と削除はちゃんと動きますが、保存されていないのでブラウザリロードでリストがリセットされちゃいますね。

データの保存先は……ブラウザ!


データの保存というと、データベース(DB)が必要になるイメージ、SIerの人は特に多いと思います。基本的にはWebアプリでも同じで、DBサーバー用意してDB作ってそこにデータ格納するという流れです。ですが、近年のブラウザ高機能化に伴いなんとブラウザにもデータストアが統合されました。

Indexed DBとWeb Storageという2種類が使え、Web StorageはさらにSession StorageとLocal Storageに別れます。今回はページやブラウザを閉じてもデータが保存されるLocal Storageを利用します!利用方法は簡単でシンプルなKey-Value型です。

// 保存
localStorage.setItem('key', 'value');

// 読み込み
localStorage.getItem('key');

// 初期化
localStorage.clear();

これだけです。シンプルでいいですね。一点だけ注意点があり、keyもvalueもString型でなくてはなりません。では実装のイメージを固めていきましょう。

  1. methodsにTodoリスト保存専用のsaveTodoToStorage関数を追加する。
  2. リストに変更が発生する箇所でsaveTodoToStorage関数を呼び出す。

1でのlocalStorageへの保存はシンプルなのでわざわざ新たな関数を追加する必要がないと思うかもしれません。ですが複数箇所からの呼び出しが発生する可能性がある関数は新たに作ることをオススメします。このレクチャーでも後で実感できると思います。

保存用の関数を作る時に気をつけるポイントがあります。前述の通りLocal StorageにはStringしか保存できません。todosはオブジェクトの配列なのでStringに変換してやる必要があります。なのでJSON.stringify()という変換メソッドを使います。

// 正しく保存されない(保存時にエラーは出ないので注意)
localStorage.setItem('todos', this.todos);

// 文字列で正しく保存される
localStorage.setItem('todos', JSON.stringify(this.todos));

2のリストに変更が発生する箇所、というのがどこかは解りますよね!そう、追加時と削除時とチェックボックス(完了/未完了)の切り替えです。追加時と削除時についてはmethodsにあるaddTododeleteTodosの一番最後でsaveTodoToStorageを呼び出しましょう。ではチェックボックス切り替え時は?ヒントは@clickの利用です。

■DEMO&サンプルソース 保存機能追加

vue

これで正しく保存はされるようになっているはずなのですが、まだ呼び出し機能を作成していないので保存がされているのか解りません……大丈夫です。

開発者ツールを利用すればLocal Storageの中身を確認できます!おっとその前に動作確認するために新たに一つ項目をTodoに追加して保存してください。

F12を押して開発者ツールを開いたら、ApplicationタブのStorageからLocal Storageを探し、ローカル環境で開発中であればfile://という項目があるので選択してください。するとこのような画面が表示されます。

05-01-dev_tool_storage

todoというKeyに対してオブジェクトの配列が文字列でValueに保存されていることが確認できるかと思います。ためしにリロードか、ページを閉じて開き直すかしてみてください。

画面は読み込みなおされるので表示されているリストは戻ってしまいますが、Local Storageには先程追加したデータが残っているか確認でき、保存されていることがわかります。さぁ、次は読み込みです!

読み込むのは簡単、タイミングは?


まずは読み込み機能を実装しましょう。まずは例によって実装の順序をイメージします。

  1. Local Storageからdatatodosにリストを代入するreadTodoFromStorage関数を実装する
  2. ページロード時にreadTodoFromStorage関数を実行する

では1の実装に入っていきましょう。まずmothodreadTodoFromStorage関数を追加します。関数内でthis.todosに対して以下のコードでLocal Storageの内容を読み込みましょう。また、取得した内容はただの文字列なのでJSON形式に変換するためにJSON.parse()メソッドも合わせて使います。

// 読み込み
this.todos = JSON.parse(localStorage.getItem('todos'));

これだけだとlocalStorageが空の場合、上記コードではthis.todosに対してnullを設定してしまいます。nullは配列ではないのでpushなどの配列の関数が動かないためエラーになります。なので、this.todosnullの場合は空の配列を代入するようif文を追加しましょう。

if (!this.todos) {
this.todos = []
}

実装順序2はdatamethodsと同じVueインスタンスのプロパティ、mountedに関数を記述して利用することで画面ロード時に好きな処理を走らせることが出来ます。今回はmountedの中で先ほど実装したreadTodoFromStorageを呼び出してみましょう。

const app = new Vue({
el: '#app',
data: { 略 },
methods: { 略 },
mounted: function(){
this.readTodoFromStorage();
}
});

それができたらdataに定義した初期表示用のダミーデータは不要になるので削除して空の配列に変更しておきましょう!

data: {
appName: 'My Vue ToDo',
todos: [], // ★空の配列に変更
newTodoTitle: '',
},

では動きを確認してみます。

■DEMO&サンプルソース 読み込み機能

2017-06-22_15h40_04

先ほど追加した4つ目のデータも表示されていたら完璧です!これで保存と読み込みの処理が完成しました。一つ注意点として、Local Storageに保存されたデータはその端末のブラウザごとに残ります。ですので共有PCの場合は誰でも見れる状態になってしまうので、保存するデータの内容には気をつけてくださいね。

保存と読込はできた!次回はフィルターだ!


保存と読込ができて基本的なTODOリストとしての動作が完成しつつあります!今回はデータストアにブラウザのLocalStorageを選択しましたが、DBや他のAPIを使ってみたいという方は是非挑戦してみてください。基本的にデータの保存と読込部分の実装行を変えるだけで基本は同じなはずです。

次回は必須機能としては最後となるフィルターを実装して行きます!アプリ画面の左下にあるAll, Working, Completedのそれぞれをクリックすることで、全て、作業中、完了済みの表示を切り替える仕組みです。アプリ完成までもう1歩ですね!

それではまた次回!

TakahiRoyte について

フルスタックエンジニアになりたい一心のSE。今はJavaScriptにハマってます。