【Laravel10 + Vuetify3】v-paginationでPaginationを実装する(2)

Laravel

前回の記事の続きです。

前回は単純にページネーションとリスト表示を連動させました。

今回はスタイル調整を少しと、絞り込み、件数変更、並び順変更を盛り込みます。

APIコントローラー編集

前回作成したAPIコントローラーを盛ります。

「app/Http/Controllers/Api/UsersController.php」を編集・保存します。

<?php

namespace App\Http\Controllers\Api;

use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use App\Models\User;

class UsersController extends Controller
{
    public function index(Request $request)
    {
        $perPage = $request->query('perPage') ?? 10;
        $domain = $request->query('domain') ?? '';
        $orderbyID = strcmp($request->query('orderbyID'), 'desc') === 0
                   ? 'desc'
                   : 'asc';
        $users = User::where('email', 'LIKE', '%' . $domain)
                    ->orderby('id', $orderbyID)
                    ->paginate($perPage);
        $empty = User::selectRaw("''");
        $domains = User::selectRaw(
                    "substr(email, instr(email,'@'), length(email))
                    as domain"
                   )
                   ->union($empty)
                   ->distinct()
                   ->orderby('domain', 'asc')
                   ->get();
        $status = 200;
        $message = 'Retrieving Users Succeeded.';
        return [
            'status' => $status,
            'message' => $message,
            'users' => $users,
            'domains' => $domains,
            'domain' => $domain,
            'perPages' => [5, 10, 20, 50, ],
            'orderbyID' => $orderbyID,
        ];
    }
}

1ページ当たりの表示件数、絞り込みドメイン、並び順の指定を盛りました。

Vueコンポーネント編集

「resources/js/App.vue」を編集・保存します。

<template>
  <div class="flex justify-start">
    <v-pagination
      v-model="currentPage"
      :length="length"
      :total-visible="6"
      :size="32"
      :color="'blue-darken-4 bg-blue-lighten-5'"
      :active-color="'white bg-blue-darken-3'"
      :rounded="lg"
      @click = "fetchUsers"
    ></v-pagination>
  </div>
  絞り込み:ドメイン<select v-model="domain" @change="changeDomain" class="mx-2 my-2 px-2 bg-sky-100 border border-gray-200">
    <option v-for="d in domains" :value="d.domain">{{ d.domain.length > 0 ? d.domain : '指定しない' }}</option>
  </select>
  表示件数<select v-model="perPage" @change="changePerPage" class="mx-2 my-2 px-2 bg-sky-100 border border-gray-200">
    <option v-for="p in perPages" :value="p">{{ p }}</option>
  </select>件/ページ<br>
  並び順:ID<select v-model="orderbyID" @change="changeOrderbyID" class="mx-2 my-2 px-2 bg-sky-100 border border-gray-200">
    <option v-for="o in orderbyIDs" :value="o">{{ orderbyIDText[o] }}</option>
  </select>
  <ul>
    <li
      v-for="user in users"
      :key="user.id"
      class="px-3 py-2 rounded-lg hover:bg-green-200"
    >
      {{ user.id }}: {{ user.name }} &lt;{{ user.email }}&gt;
    </li>
  </ul>
</template>
<script>
export default {
  data () {
    return {
      perPage: 10,
      currentPage: 1,
      length: 1,
      users: [],
      domains: [],
      perPages: [],
      domain: '',
      orderbyID: 'asc',
      orderbyIDs: ['asc', 'desc'],
      orderbyIDText: {asc: '昇順', desc: '降順'},
      apiBase: location.protocol + '//' + location.host + '/api/users',
    }
  },
  methods: {
    apiUrl () {
      return this.apiBase
             + '?page=' + this.currentPage
             + '&perPage=' + this.perPage
             + '&domain=' + this.domain
             + '&orderbyID=' + this.orderbyID;
    },
    async fetchUsers () {
        const url = this.apiUrl();
        const res = await fetch(url);
        const json = await res.json();
        this.users = json.users.data;
        this.domains = json.domains;
        this.perPages = json.perPages;
        this.length = json.users.last_page;
    },
    changeDomain () {
      this.currentPage = 1;
      this.fetchUsers();
    },
    changePerPage () {
      this.currentPage = 1;
      this.fetchUsers();
    },
    changeOrderbyID () {
      this.fetchUsers();
    }
  },
  mounted () {
    this.fetchUsers();
  }
}
</script>

v-paginationのテキストカラーは「blue-darken-4」などで指定できますが、背景色は「bg-」をカラーコードの前につければ反映されます。

borderの輪郭については、「rounded=”lg”」などで指定できます。

詳細はこちらのページで確認できます。

Border radius — Vuetify
Use border utilities to quickly style the border-radius of any element.

ブラウザ確認

WEBブラウザを再読み込みします。

ドメインの絞り込みをしてみます。

このように表示が変更されました。

表示件数を変更してみます。

このように表示が変わりました。

並び順を変更してみます。

このように表示が変わりました。

ページを切り替えてみます。

絞り込み、表示件数、並び順を維持したままページ切替ができています。

今回はここまでです。お疲れさまでした。

コメント

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