10
10

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 5 years have passed since last update.

LaravelとVuetable-2でページネーション付きテーブルを使ってみる

Posted at

LaravelとVuetable-2でページネーション付きテーブルを使ってみる

screen.gif

vuetable-2というVue用の高機能なテーブルコンポーネントを見つけたので、Laravelをバックエンドにして使ってみたサンプルです。

プロジェクト作成

まず適当な名前でプロジェクトを作成します。

laravelコマンドを使うなら以下のような感じで。

laravel new laravel-vuetable-2

テーブル作成

元々存在しているxxxx_create_users_tableを改変し、名前・メール・住所フィールドの入ったusersテーブルを作成します。

    public function up()
    {
        Schema::create('users', function (Blueprint $table) {
            $table->increments('id');
            $table->string('name');
            $table->string('email');
            $table->string('address');
            $table->timestamps();
        });
    }
php artisan migrate

Userモデルは最初からあるものをそのまま使います。

ダミーデータ作成

LaravelにバンドルされているFakerを使ってダミーデータを1000件ほど作成しておきます。

database/seeds/DatabaseSeeder.phprunメソッドに追加します。

    public function run()
    {
        DB::table('users')->delete();
        $faker = Faker\Factory::create('ja_JP');
        for ($i = 0; $i < 1000; $i++) {
            User::create([
                'name' => $faker->name,
                'email' => $faker->email,
                'address' => $faker->address,
            ]);
        }
    }
php artisan db:seed

vuetable-2の導入

vuetable-2をnpmで導入します。

npm i vuetable-2 -D

一覧テーブルの表示

まずはとにかく一覧を表示してみます。

API

一覧表示のAPI部分を作成します。

routes/api.phpに元から書いてあるルートを上書きします。

<?php
use Illuminate\Http\Request;

Route::middleware('api')->get('/user', function(Request $request) {
    return App\User::paginate((int)$request->per_page);
});

api/userにアクセスしてみて一覧が取得されることを確認してください。

  • per_pageは、Vuetableから渡される1ページあたりの行数です。

Vueコンポーネント

今回は元々あるresources/assets/js/components/Example.vueに上書きします。
コンポーネントを新規作成しても、もちろん構いません。

<template>
  <vuetable
    api-url="api/user"
    :fields="['name', 'email', 'address']"
  ></vuetable>
</template>

<script>
import Vuetable from 'vuetable-2'

export default {
  components: {
    Vuetable
  }
}
</script>
  • api-url属性は、データを取得するAPIのURLです。
  • fields属性は、表示するフィールドです。

bladeテンプレート

表示するガワを作成します。resources/views/welcome.blade.phpを上書きして使います。

<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta name="csrf-token" content="{{ csrf_token() }}">
    <title>Vuetable-2サンプル</title>
    <link href="{{ asset('css/app.css') }}" rel="stylesheet">
</head>
<body>
    <div id="app">
        <example></example>
    </div>
    <script src="{{ asset('js/app.js') }}"></script>
</body>
</html>

これでブラウザでアクセスすると、一覧が10件表示されます。

ページネーション

次にページネーション用のナビゲーションを設置してみます。幸いにもVuetableのページネーションは、Laravelのページネーションの機構をほぼそのまま使うことができます。

Vueコンポーネント

ページネーション用のコンポーネントを追加します。

resources/assets/js/components/Example.vue

<template>
  <div>
    <vuetable
      ref="vuetable"
      api-url="api/user"
      :fields="['name', 'email', 'address']"
      pagination-path=""
      @vuetable:pagination-data="onPaginationData"
    ></vuetable>
    <vuetable-pagination
      ref="pagination"
      @vuetable-pagination:change-page="onChangePage"
    ></vuetable-pagination>
  </div>
</template>

<script>
import {Vuetable, VuetablePagination} from 'vuetable-2'

export default {
  components: {
    Vuetable, VuetablePagination
  },
  methods: {
    onPaginationData(data) {
      this.$refs.pagination.setPaginationData(data)
    },
    onChangePage(page) {
      this.$refs.vuetable.changePage(page)
    }
  }
}
</script>

ブラウザで確認すると、スタイルは当たっていませんが、ページネーションは動くはずです。

  • VuetablePaginationコンポーネントでページネーションを表示します。
  • Laravelのpaginateメソッドから返されるデータと合わせるために、Vuetableコンポーネントのpagination-path属性をセットしています。
  • API側から正常にデータを取得できたとき、Vuetableコンポーネントのpagination-dataイベントが発火するので、そのときにVuetablePaginationコンポーネントのsetPaginationDataメソッドへページネーションデータを渡してページネーションを構築します。
  • ページネーションを操作したとき、VuetablePaginationコンポーネントのchange-pageイベントが発火するので、そのときVuetableコンポーネントのchangePageメソッドへページ情報を渡して当該ページを取得します。

スタイリング

VuetableはSemantic UIの使用を前提にしています。LaravelのデフォルトはBootstrapですので、スタイリングを変更してやります。

resources/assets/js/components/Example.vue

<template>
  <div>
    <vuetable
      ref="vuetable"
      api-url="api/user"
      :fields="['name', 'email', 'address']"
      pagination-path=""
      @vuetable:pagination-data="onPaginationData"
    ></vuetable>
    <vuetable-pagination
      ref="pagination"
      @vuetable-pagination:change-page="onChangePage"
      :css="css"
    ></vuetable-pagination>
  </div>
</template>

<script>
import {Vuetable, VuetablePagination} from 'vuetable-2'

export default {
  components: {
    Vuetable, VuetablePagination
  },
  data() {
    return {
      css: {
        wrapperClass: 'pagination',
        activeClass: 'active',
        disabledClass: 'disabled',
        icons: {
          first: 'glyphicon glyphicon-backward',
          prev: 'glyphicon glyphicon-triangle-left',
          next: 'glyphicon glyphicon-triangle-right',
          last: 'glyphicon glyphicon-forward'
        }
      }
    }
  },
  methods: {
    onPaginationData(data) {
      this.$refs.pagination.setPaginationData(data)
    },
    onChangePage(page) {
      this.$refs.vuetable.changePage(page)
    }
  }
}
</script>

<style>
.pagination a {
  cursor: pointer;
  border: 1px solid lightgray;
  padding: 5px 10px;
}
.pagination a.active {
  color: white;
  background-color: #337ab7;
}
.pagination a.btn-nav.disabled {
  color: lightgray;
  cursor: not-allowed;
}
</style>
  • VuetablePaginationコンポーネントのcss属性にクラスやアイコンを指定します。

まとめ

LaravelとVuetable-2の相性はとても良いことが分かりました。

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

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?