LaravelのJetstreamのダッシュボード画面(Vue.js+Inertia.js)にデータの一覧表示させる
前提条件
- laravelプロジェクトにJetstream,Vue.js,Inertia.jsがインストールされている。
作るもの
- タイトルとコンテンツの2つの項目を持つシンブルなブログ
モデル・コントローラーの作成
Blogモデルの作成はphp artisan make:modelコマンドで行う。-m を追記すると、モデルと同時にマイグレーションファイルの作成される。
% php artisan make:model Blog -m
モデル用のコントローラーを作成する
% php artisan make:controller BlogController --resource
※リソースは必須でない
Blogテーブルの作成
マイグレーションファイル編集して、title,contentの項目を追加する。
public function up()
{
Schema::create('blogs', function (Blueprint $table) {
$table->id();
$table->string('title');
$table->text('content');
$table->timestamps();
});
}
マイグレーションしてテーブルを作成する。
php artisan migrate
app¥Models¥Blog.phpファイル(モデルクラス)に追加した列の情報を追記する。
class Blog extends Model
{
use HasFactory;
protected $fillable = [
'title',
'content'
];
}
ルーティングの設定
web.phpにルーティングを追加する。
ルーティングにはnameメソッドで名前blog.indexをつけており名前を利用することでこのルーティングにアクセスを行うことができる。(必須ではない)
ミドルウェアのauthを利用することでログインしているユーザのみアクセス可能となるアクセス制限を行うことができる。(必須ではない)
//略
use App\Http\Controllers\BlogController;
//略
Route::get('/blogs', [BlogController::class, 'index'])
->name('blog.index')
->middleware('auth');
すると、/blogsにアクセスするとログイン画面が表示される。
/で事前に登録しておくと、ログイン出来て、indexにアクセスできる。
しかし、インデックスファイルを作ってないのでもちろん画面は真っ白。
リンクの作成
ログインすると/dashboardにリダイレクトされる。/dashboardで表示されるページの内容はresources¥js¥Pagesの下に保存されているDashboard.vueファイルに記述されている。
通常、Laravelで利用されているviewのBladeファイルはresources¥viewの下に保存されているが、Inertia.jsではrenderメソッドで指定するvueファイルはresources¥js¥Pagesに保存されている。
AppLayout.vueファイルを開いてBlogページへのリンクを設定する。routeメソッドに設定しているblog.indexはweb.phpファイルのルーティングで設定したnameの値。
<!-- Navigation Links -->
<div
class="hidden space-x-8 sm:-my-px sm:ms-10 sm:flex"
>
<NavLink
:href="route('dashboard')"
:active="route().current('dashboard')"
>
Dashboard
</NavLink>
</div>
<div
class="hidden space-x-8 sm:-my-px sm:ms-10 sm:flex"
>
<NavLink
:href="route('blog.index')"
:active="route().current('blog.index')"
>
Blog
</NavLink>
</div>
今、リンクをクリックしても何も起こらない。inertia.jsはPHPとは異なり、更新後はビルドを行う必要があるのでnpm run runコマンドを実行しておく必要があるため。また、まだページが作成できていないため。
indexページの作成
/blogsにアクセスした場合に表示されるページをBlogController.phpファイルのindexメソッドで指定する。Inertiaのrenderメソッドで表示するページを設定する。resources¥js¥Pagesの下にBlogディレクトリを作成する。その後DashBoard.vueファイルを複製して保存し、名前をIndex.vueに変更する。
use Inertia\Inertia; //追加
class BlogController extends Controller
{
public function index(){
return Inertia::render('Blog/Index');
}
作成したIndex.vueファイルを開いてwelcomeコンポーネントを削除し、template #headerタグの中にあるDashboardをBlogに変更する。
<script setup>
import AppLayout from "@/Layouts/AppLayout.vue";
</script>
<template>
<AppLayout title="Blog">
<template #header>
<h2 class="font-semibold text-xl text-gray-800 leading-tight">
Blog
</h2>
</template>
</AppLayout>
</template>
/blogsにアクセスすると作成したBlog/Index.vueファイルの内容が表示される。
Seeding(データの格納)
Index.vueにアクセスした際にブログの一覧を表示させるためにはblogテーブルにデータを登録する必要がある。
Seeding機能を利用することでBlogテーブルに複数のダミーデータを短時間で簡単に挿入することができる。
php artisan make:factoryコマンドを利用してテーブルに挿入するデータの構造を記述したFactoryファイルを作成する。
% php artisan make:factory BlogFactory --model=Blog
database¥factoriesディレクトリにBlogFactory.phpファイルが作成されるのでtitle, content列に挿入するダミーデータの定義を行う。
public function definition()
{
return [
'title' => $this->faker->sentence,
'content' => $this->faker->text,
];
}
次にdatabase¥seeders下にあるDatabaseSeeder.phpファイルを開いて下記を設定する。User用の設定が行っているので行を複製してUserをBlogに変更する。
public function run()
{
// \App\Models\User::factory(10)->create();
\App\Models\Blog::factory(10)->create();
}
これでSeeding機能の設定は完了。最後に実際にデータを挿入するphp artisan db:seedコマンドを実行。successfullyのメッセージが表示されればデータの挿入は完了。
% php artisan db:seed
INFO Seeding database.
データが挿入されたかどうかphp artisan tinkerを利用して確認することができる。
% php artisan tinker
Psy Shell v0.12.0 (PHP 8.3.1 — cli) by Justin Hileman
>App\Models\Blog::all()
=> Illuminate\Database\Eloquent\Collection {#4560
all: [
App\Models\Blog {#4562
id: "1",
title: "Impedit sed perferendis explicabo.",
//略
Blogデータの一覧表示
Seederを利用して挿入したデータをBlogController.phpとIndex.vueファイルを利用してブラウザに表示する。
BlogController.phpのindexメソッド内でBlogモデルを利用してblogsテーブルに保存された全データを取得。取得したデータはrenderメソッドの第二引数を利用してvueファイルに渡す。
//略
use Inertia\Inertia;
use App\Models\Blog;
class BlogController extends Controller
{
public function index(){
return Inertia::render('Blog/Index',['blogs' => Blog::all()]);
}
//略
Index.vueファイルではBlogController.phpから渡された変数blogsのデータを受け取るためにpropsを利用。propsで取得したデータはv-forを利用して展開。
<script setup>
import AppLayout from "@/Layouts/AppLayout.vue";
defineProps({
blogs: Array,
});
</script>
<template>
<AppLayout title="Blog">
<template #header>
<h2 class="font-semibold text-xl text-gray-800 leading-tight">
Blog
</h2>
</template>
<div class="py-12">
<div class="max-w-7xl mx-auto sm:px-6 lg:px-8">
<table>
<thead>
<tr>
<th>タイトル</th>
<th>コンテンツ</th>
</tr>
</thead>
<tbody>
<tr v-for="blog in blogs" :key="blog.id">
<td class="border px-4 py-2">{{ blog.title }}</td>
<td class="border px-4 py-2">{{ blog.content }}</td>
</tr>
</tbody>
</table>
</div>
</div>
</AppLayout>
</template>
ブラウザで確認するとテーブルに保存されている10件分のBlogデータが一覧表示される。