Laravel10 + Vue3 で、vuejs-paginate-next コンポーネントを使ってPaginationを実装していきます。
![](https://macocci7.net/blog/wp-content/uploads/cocoon-resources/blog-card-cache/13b44a77bc1d6983ae57464406c45b68.png)
前提条件
- Ubuntu上で作業しています
- PHP8.2以降インストール済
- Composer v2以降インストール済
これからやること
- 環境構築(Laravel10 + Vue3 + vuejs-paginate-next)
- マイグレーション
- API作成
- ルーティング(API)
- ブラウザ確認(API)
- Vueコンポーネント編集
- ブラウザ確認
環境構築(Laravel10 + Vue3 + vuejs-paginate-next)
Laravel10プロジェクト「pagination-vue3」を作成します。
composer create-project laravel/laravel:^10 pagination-vue3
![](https://macocci7.net/blog/wp-content/uploads/2024/02/laravel_vue3_pagination01-1.png)
「pagination-vue3」フォルダに入って、
viteプラグインのvue3をインストールします。
npm install @vitejs/plugin-vue --save-dev
![](https://macocci7.net/blog/wp-content/uploads/2024/02/laravel_vue3_pagination02.png)
プロジェクトトップにある「vite.config.js」にvueの設定を追記します。
import vue from "@vitejs/plugin-vue"
vue(),
![](https://macocci7.net/blog/wp-content/uploads/2024/02/laravel_vue3_pagination03.png)
Vue3用のページネーションコンポーネントvuejs-paginate-nextをインストールします。
![](https://macocci7.net/blog/wp-content/uploads/cocoon-resources/blog-card-cache/13b44a77bc1d6983ae57464406c45b68.png)
npm install vuejs-paginate-next --save
![](https://macocci7.net/blog/wp-content/uploads/2024/02/laravel_vue3_pagination04.png)
「resources/js/app.js」にVue3とvuejs-paginate-nextの設定を追記します。
追記する内容:
import {createApp} from 'vue'
import Paginate from "vuejs-paginate-next";
import App from './App.vue'
createApp(App).use(Paginate).mount("#app")
![](https://macocci7.net/blog/wp-content/uploads/2024/02/laravel_vue3_pagination05.png)
同じフォルダ内に「App.vue」ファイルを作成して編集・保存します。
<template>
<div>
<paginate
:page-count="20"
:page-range="3"
:margin-pages="2"
:click-handler="clickCallback"
:prev-text="'Prev'"
:next-text="'Next'"
:container-class="'pagination'"
:page-class="'page-item'"
>
</paginate>
</div>
</template>
<script>
import Paginate from 'vuejs-paginate-next';
export default {
components: {
paginate: Paginate,
},
methods: {
clickCallback (pageNum) {
console.log(pageNum)
}
},
}
</script>
<style lang="css">
@import "https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css";
</style>
ビューファイルを作成します。
php artisan make:view users
![](https://macocci7.net/blog/wp-content/uploads/2024/02/laravel_vue3_pagination06.png)
「resources/vies/users.blade.php」を編集・保存します。
<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Laravel Vite Vue</title>
@vite(['resources/css/app.css', 'resources/js/app.js'])
</head>
<body>
<div id="app"></div>
</body>
</html>
「routes/web.php」を開いてルーティングを追記します。
Route::get('/users', function () {
return view('users');
});
![](https://macocci7.net/blog/wp-content/uploads/2024/02/laravel_vue3_pagination07.png)
WEBサービスを起動して一度表示確認してみましょう。
まずはviteを起動します。
npm run dev
![](https://macocci7.net/blog/wp-content/uploads/2024/02/laravel_vue3_pagination08.png)
別のターミナルでlaravelのWEBサービスを起動します。
php artisan serve
![](https://macocci7.net/blog/wp-content/uploads/2024/02/laravel_vue3_pagination09.png)
WEBブラウザで「http://127.0.0.1:8000/users」にアクセスします。
![](https://macocci7.net/blog/wp-content/uploads/2024/02/laravel_vue3_pagination10.png)
ページネーションが表示されました。bootstrap5のスタイルを適用しています。
ページリンクをクリックした際のコールバックにより、
コンソールにページ番号が表示されています。
このページネーションはガワだけなので、ページリンクをクリックした際の挙動を実装していく必要があります。
マイグレーション
プロジェクトトップにある「.env」を編集します。
DB_CONNECTION=sqlite
に修正して、それ以外のDB項目を削除します。
![](https://macocci7.net/blog/wp-content/uploads/2024/02/laravel_vue3_pagination11.png)
「database/seeders/DatabaseSeeder.php」を編集します。
// \App\Models\User::factory(10)->create();
の箇所を修正します。
\App\Models\User::factory(150)->create();
![](https://macocci7.net/blog/wp-content/uploads/2024/02/laravel_vue3_pagination12.png)
シーダーオプション付きでマイグレーションを実行します。
php artisan migrate --seed
![](https://macocci7.net/blog/wp-content/uploads/2024/02/laravel_vue3_pagination13.png)
SQLiteのファイルを作成するか訊かれるので、
[←]キーを押して「Yes」を選択し[Enter]で確定します。
![](https://macocci7.net/blog/wp-content/uploads/2024/02/laravel_vue3_pagination14.png)
ユーザーデータが150件生成されています。
API作成
API用のコントローラーを作成します。
php artisan make:controller Api/UsersController
![](https://macocci7.net/blog/wp-content/uploads/2024/02/laravel_vue3_pagination15.png)
「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,
'selectedDomain' => $domain,
'perPages' => [5, 10, 20, 50, ],
'orderbyID' => $orderbyID,
];
}
}
このコントローラーは以前の記事で作成したコントローラーをAPIに転用したものです。
ルーティング(API)
「routes/api.php」を開いて追記します。
Route::get('/users', [\App\Http\Controllers\Api\UsersController::class, 'index']);
![](https://macocci7.net/blog/wp-content/uploads/2024/02/laravel_vue3_pagination16.png)
ブラウザ確認(API)
WEBブラウザで
http://127.0.0.1:8000/api/users
にアクセスします。
![](https://macocci7.net/blog/wp-content/uploads/2024/02/laravel_vue3_pagination17.png)
ユーザーデータのページネーションの結果がJSON形式で表示されています。
Vueコンポーネント編集
先程作成したApp.vueでAPIからJSONを取得し、
ページリンクをクリックした際のコールバックで
ユーザー一覧を表示切替できるようにしていきます。
<template>
<div>
<paginate
v-model="currentPage"
:page-count="pageCount"
:page-range="3"
:margin-pages="2"
:click-handler="clickCallback"
:prev-text="'<'"
:next-text="'>'"
:container-class="'pagination'"
:page-class="'page-item'"
>
</paginate>
絞り込み:ドメイン<select v-model="domain" @change="changeDomain">
<option v-for="d in domains" :value="d.domain">{{ d.domain.length > 0 ? d.domain : '指定しない' }}</option>
</select>
表示件数<select v-model="perPage" @change="changePerPage">
<option v-for="p in perPages" :value="p">{{ p }}</option>
</select>件/ページ<br>
並び順:ID<select v-model="orderbyID" @change="changeOrderbyID">
<option v-for="o in orderbyIDs" :value="o">{{ orderbyIDText[o] }}</option>
</select>
<ul class="users">
<li v-for="u in users.data" class="user">{{ u.id }}: {{ u.name }} <{{ u.email }}></li>
</ul>
</div>
</template>
<script>
import Paginate from 'vuejs-paginate-next';
export default {
components: {
paginate: Paginate,
},
data () {
return {
perPage: 10,
pageCount: 1,
currentPage: 1,
users: [],
domains: [],
perPages: [],
domain: '',
orderbyID: 'asc',
orderbyIDs: ['asc', 'desc'],
orderbyIDText: {asc: '昇順', desc: '降順'},
apiBase: location.protocol + '//' + location.host + '/api/users'
}
},
methods: {
apiUrl (pageNum, perPage, domain, orderbyID) {
return this.apiBase
+ '?page=' + pageNum
+ '&perPage=' + perPage
+ '&domain=' + domain
+ '&orderbyID=' + orderbyID;
},
async fetchUsers (pageNum, perPage, domain, orderbyID) {
const url = this.apiUrl(pageNum, perPage, domain, orderbyID);
const res = await fetch(url);
const json = await res.json();
this.users = json.users;
this.domains = json.domains;
this.perPages = json.perPages;
this.pageCount = json.users.last_page;
},
clickCallback (pageNum) {
this.fetchUsers(pageNum, this.perPage, this.domain, this.orderbyID);
this.currentPage = pageNum;
},
changeDomain () {
this.fetchUsers(1, this.perPage, this.domain, this.orderbyID);
this.currentPage = 1;
},
changePerPage () {
this.fetchUsers(1, this.perPage, this.domain, this.orderbyID);
this.currentPage = 1;
},
changeOrderbyID () {
this.fetchUsers(this.currentPage, this.perPage, this.domain, this.orderbyID);
}
},
mounted () {
this.fetchUsers(this.currentPage, this.perPage, this.domain, this.orderbyID);
}
}
</script>
<style lang="css">
@import "https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css";
</style>
ブラウザ確認
WEBブラウザで
http://127.0.0.1:8000/users
にアクセスします。
![](https://macocci7.net/blog/wp-content/uploads/2024/02/laravel_vue3_pagination18-1.png)
ページネーション、絞り込み条件、並び順、ユーザー一覧が表示されました。
絞り込み条件や並び順、ページを変更してみます。
![](https://macocci7.net/blog/wp-content/uploads/2024/02/laravel_vue3_pagination19.png)
しっかり反映されています。
今回はここまでです。お疲れさまでした。
続きはこちら。
コメント