Laravel+Vue/Vuetify Data tablesで一覧作成

前回は非同期バリデーションとともに登録を行いました。
今回はLaravelのSeederでテストデータを生成して、Vue/VuetifyのData tablesを使って登録した情報の一覧機能を作成します。
LaravelのPaginationと連携することで簡単にデータ一覧を作成することができます。

開発環境

Laradock v10
Laravel 7
Vue 2.6

Laravel:Seederでテストデータ生成

Faker日本語化

Fakerで作成するデータを日本語にします。

config/app.php
-----
//    'faker_locale' => 'en_US',
    'faker_locale' => 'ja_JP',
-----

Factoryを作成

# php artisan make:factory ItemFactory --model=Models/Item

テキストボックス:Fakerで名前を生成
テキストエリア:Fakerでリアルテキストを生成
ラジオボタン:RADIOSで定義した配列のキーをランダムに取得
セレクトボックス:SELECTSで定義した配列のキーをランダムに取得
チェックボックス:CHECKSで定義した配列のキーを1~8個までランダムに取得した配列をカンマ区切りのテキストとして取得

database/factories/ItemFactory.php
-----
<?php

/** @var \Illuminate\Database\Eloquent\Factory $factory */

use App\Models\Item;
use Faker\Generator as Faker;

$factory->define(Item::class, function (Faker $faker) {
    return [
        'textbox' => $faker->name,
        'textarea' => $faker->realText(50),
        'radiobtn' => $faker->randomElement($array = array_keys(\Config::get('const.RADIOS'))),
        'select' => $faker->randomElement($array = array_keys(\Config::get('const.SELECTS'))),
        'checkbox' => implode(',', $faker->randomElements(
                          $array = array_keys(\Config::get('const.CHECKS')), 
                              $faker->numberBetween($min = 1, $max = 8)
                          )
                      ),
    ];
});
-----

Seederを作成

# php artisan make:seeder ItemTableSeeder

作成したFactoryを元に50個のデータを登録させます。

database/seeds/ItemTableSeeder.php
-----
<?php

use Illuminate\Database\Seeder;
use App\Models\Item;

class ItemTableSeeder extends Seeder
{
    /**
     * Run the database seeds.
     *
     * @return void
     */
    public function run()
    {
        factory(Item::class, 50)->create();
    }
}
-----

実行

# php artisan db:seed --class=ItemTableSeeder
laravel-vue-vuetify-datatable-1

Laravel:コントローラー

Route::resourceによってRESTfulなルーティングがなされていますので、リスト表示はindexメソッドでItemリストを返しましょう。

app/Http/Controllers/Ajax/User/ItemController.php
-----

use App\Models\Item;

    public function index()
    {
        $status = 200;
        $message = null;
        $data = Item::orderBy('id', 'desc')->paginate(3);
        return response()->json(['result' => $data, 'status' => $status, 'message' => $message]);
    }
-----

※1ページ当たりのデータ数を「3」にしていますが、ちゃんと定義したほうがいいですね。

ItemComponentにData tables

Vuetify/Data tablesで最低限必要な情報を表示されてみます。

resources/js/componets/User/ItemComponent.vue
-----
<template>
<div>
  <h1>UserItem</h1>

  <router-link to="/user/item/add">
    <v-btn>新規登録</v-btn>
  </router-link>


  <v-data-table
    :headers="headers"
    :items="items"
    :items-per-page="itemsPerPage"
    :page.sync="page"
    :server-items-length="total"
    :footer-props="{
      itemsPerPageOptions: [itemsPerPage],
      showFirstLastPage: true,
    }"
    class="elevation-1"
    @update:page = "getData"
  >
  
    <template v-slot:item.actions="{ item }">
      <v-icon
        class="mr-2"
        @click="editItem(item)"
      >
        mdi-pencil
      </v-icon>
      <v-icon
        @click="deleteItem(item)"
      >
        mdi-delete
      </v-icon>
    </template>
  
  </v-data-table>


</div>
</template>

<script>
  export default {
    data () {
      return {
        headers: [
          { text: 'ID', value: 'id', align: 'start', sortable: false, },
          { text: 'Textbox', value: 'textbox', sortable: false, },
          { text: 'Actions', value: 'actions', align: 'end', sortable: false },
        ],
        page: 1,
        itemsPerPage: 3,
        total: 0,
        items: [],
      }
    },
    created() {
      this.getData(this.page);
    },
    methods: {
      getData(page){
        axios.get('/ajax/user/item', {
          params: {
            page: parseInt(page),
          }
        })
        .then((res) => {
          let result = res.data.result;
          this.items = result.data;
          this.total = result.total;
          this.itemsPerPage = result.per_page;
        })
        .catch((err) => {
          console.log(err);
        })
      }
    }
  }
</script>
-----

ヘッダの表示設定、データ、1ページ当たりのデータ数、全データ数を設定するだけです。
LaravelのPaginateはこれらの値を自動的に出力してくれるので大変便利ですね!
また、page.syncにpageと同期するプロパティを設定し、@update:pageにページアイコンをクリックしたときのメソッドを設定するだけでData tableのページネーションが動作します。

laravel-vue-vuetify-datatable-2

ヘッダについて

headersで設定します。
text:表示名
value:データベーステーブルのカラム名
align:表示位置(start/center/end)
sortable:ソート用アイコンの表示/非表示

フッタについて

デフォルトではRows Per Pageで1ページ当たりのデータ数を変更できるようになっていますが、今回は不要なのでitemsPerPageOptionsでitemsParPageのみ設定しておきます。
これに何も設定しないとデフォルトのitemsPerPage(1ページ当たり10件)が設定されてしまいます。
※編集と削除のアイコンも設置しましたが、メソッドの実装はまた次回以降で!

コメント

タイトルとURLをコピーしました