beta

Vue.jsでIndexedDBとプラグイン「Dexie」で楽々クライアントデータベースを作成する

ブラウザで使える簡易データベース・IndexedDBをVue.jsアプリで使ってみました。そのままHTMLのAPIを使ってもいいですが、より簡単に操作ができる「Dexie」プラグインで簡易データベースとして使ってみました。

公開日:2020年1月9日

IndexedDBとは

IndexedDBは、モダンブラウザに実装されたデータを保存するためのAPIです。保存するデータは「キー・バリュー型」になっているので、簡単なデータベースとしても使えます。

IndexedDB API

LocalStorageよりも大きなデータを保持できるので、使っていくうちにデータが増えていくようなユーザーデータを格納するのに最適です。

実際に、Twitterのブラウザ版などでも利用されています。

Dexie.jsとは

IndexedDBを扱いやすくするJavascriptのライブラリ・プラグインです。公式サイトのサンプルにもあるように、よくあるORMラッパー的な書き方で使うことができます。

Dexie.js

下記は、公式ページにある、データの追加と取得のサンプルの解説版です。

// データの追加
db.friends.put({name: "Nicolas", shoeSize: 8}).then (function(){
  // データの取得
  return db.friends.get('Nicolas');
}).then(function (friend) {
  // 処理
}).catch(function(error) {
 // エラー処理
});

簡単ですね。

Vue.jsで実際に使ってみる

Vue.jsアプリで使ってみます。

インストール

まず、プラグインをインストールします。Vue.jsアプリのpackage.jsonがあるところで、

yarn add dexie

と実行すれば追加されます。

Dexieの呼び出し

呼び出しはどこでも良いのですが、わかりやすくApp.vueで呼び出してみましょう。

<template>
  <div id="main">
  </div>
</template>

<script>
import Vue from 'vue';

import Dexie from 'dexie';

export default Vue.extend({
  name: 'app',
  data() {
    list: []
  },
  methods: {
  }
});
</script>

これだけで、Vueアプリ内でDexieを使ってIndexedDBの操作ができます。簡単ですね。

Dexieのコマンドを使ってみる

Dexieは公式リファレンスが充実している方なので、そちらを確認する方が早いのですが、簡単によく使う部分を書いてみます。

それそれ、メソッド名は仮ですので、自由に変更してください。

DBの作成

まずはDBを作成します。methodsに適当な関数を作成して、

createDB(){
  const db = new Dexie('データベース名');
}

これでDBを作成するコマンドをおしまいです。

テーブルの作成

続いてテーブルを作成します。

createTable(){
  db.version(1).stores({
      テーブル名: `キー1, キー2`
  });
}

テーブルの作成には「.version().stores」を使います。

テーブルの定義(スキーマ)は、「テーブル名: カンマ区切りのキー一覧」というフォーマットです。

オートインクリメント(++)や、インデックス([])なども使えます。

データの追加

こちらは先ほどの例に出てきた部分ですが、

addData(){
  db.テーブル名.put({キー1: バリュー1, キー2: バリュー2,,,,})
}

という形で入れます。よくあるやつですね。

データの取得&whereで絞り込み

続いて、データの取得です。

簡単なやつは、キーを指定して取得するパターンです。

getData(){
  db.テーブル名.get('キー')  
}

注意したいのは、getメソッドで指定できるのは、主キーだけになります。先ほどのデータの追加の例でいうと「キー1」だけです。

これだけだと、使い勝手の悪いデータベースですが、Dexieでは他のキーでの検索もできます。

searchData(){
  db.テーブル名.where({キー: バリュー})  
}

出力を変数に入れたい場合は、

const result = db.テーブル名.where({キー: バリュー}).toArray()

とすればOKです。

async awaitを使う

IndexedDBは非同期処理なので、IndexedDBからデータを取得して描画をする際は、async/awaitを使うと良いでしょう。

 async getData(){
  const result = db.テーブル名.where({キー: バリュー}).toArray()
  // 何か処理して
  this.list = result
}

といった感じでasync/awaitを使うことで、IndexedDBからの返答を操作する際に、コールバック地獄をせずに簡単に書くことができます。

IndexedDBを使ってみた感想

データの処理が驚くほど早い

ローカルデータなので当たり前なのですが、データの読み出しがめちゃくちゃ早いです。データを格納しておけば数百件くらいのデータなら0.1秒もしないで取得できます。

Vue.jsの場合、外部のAPIからデータを取ることが多いので、このスピード感は感動します。

非同期なので画面を描画させる際は処理が必要

IndexedDBは非同期処理なので、データを処理してからその内容をアプリ側に反映させるには再描画が必要になります。Vue.jsならcomputedで格納したデータを操作するのが良いでしょう。

DexieがあればVue.jsでも簡単にIndexedDBが操作できる

ここまで簡単に使えるのはある意味Dexieのおかげです。動作も軽量なので気軽にVue.jsアプリに追加できるのがいいところですね。


まだ使い始めたばかりなので簡単ですが、Vue.jsアプリでIndexedDBクライアントデータベースを使ってみました。

完全にユーザーローカルで完結してしまうため、使いどころは考えないとですが、PWAなどでユーザーデータを格納して定時同期するなど、使い勝手は良さそうだと感じました。