LivewireでBreeze認証のCRUD
Laravelのlivewire-breezeプロジェクト作成
composer create-project –prefer-dist laravel/laravel livewire-breeze
breezeとlivewireのインストール
composer require laravel/breeze –dev
php artisan breeze:install
composer require livewire/livewire
resources/views/layouts/app.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"> <meta name="csrf-token" content="{{ csrf_token() }}"> <title>{{ config('app.name', 'Laravel') }}</title> <!-- Fonts --> <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Nunito:wght@400;600;700&display=swap" <!-- Styles --> <link rel="stylesheet" href="{{ asset('css/app.css') }}"> <!-- Scripts --> <script src="{{ asset('js/app.js') }}" defer></script> @livewireStyles </head> <body class="font-sans antialiased"> <div class="min-h-screen bg-gray-100"> @include('layouts.navigation') <!-- Page Heading --> <header class="bg-white shadow"> <div class="px-4 py-6 mx-auto max-w-7xl sm:px-6 lg:px-8"> {{ $header }} </div> </header> <!-- Page Content --> <main> {{ $slot }} </main> </div> @livewireScripts </body> </html>
npmでJavascriptをインストール
npm install && npm run dev
データベース作成
php artisan make:migration create_posts_table
edit database/migrations/create_posts_table.php
use Illuminate\Database\Migrations\Migration; use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; class CreatePostsTable extends Migration { /** * Run the migrations. * * @return void */ public function up() { Schema::create('posts', function (Blueprint $table) { $table->id(); $table->string('title'); $table->text('description'); $table->timestamps(); }); } /** * Reverse the migrations. * * @return void */ public function down() { Schema::dropIfExists('posts'); } }
マイグレーション実行
php artisan migrate
Postモデル
php artisan make:model Post -m
edit app/Models/Post.php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Post extends Model
{
use HasFactory;
protected $fillable = [
'title',
'description'
];
}
コントローラー作成
php artisan make:controller PostController
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class PostController extends Controller
{
/**
* Display a listing of the resource.
*
* @return \Illuminate\Http\Response
*/
public function index()
{
return view('posts');
}
}
edit routes/web.php
use App\Http\Controllers\PostController;
use Illuminate\Support\Facades\Route;
Route::get('/', function () {
return view('welcome');
});
Route::get('posts', [PostController::class,'index'])->name('posts.index');
Route::get('/dashboard', function () {
return view('dashboard');
})->middleware(['auth'])->name('dashboard');
require __DIR__ . '/auth.php';
Create Livewire Component
php artisan make:livewire PostForm
resources/views/postsblade.php
<x-app-layout>
<x-slot name="header">
<h2 class="text-xl font-semibold leading-tight text-gray-800">
Post
</h2>
</x-slot>
<div class="py-12">
<div class="mx-auto max-w-7xl sm:px-6 lg:px-8">
<div class="overflow-hidden bg-white shadow-sm sm:rounded-lg">
<div class="p-6 bg-white border-b border-gray-200">
<livewire:post-form />
</div>
</div>
</div>
</div>
</x-app-layout>
app/Http/Livewire/PostForm.php
namespace App\Http\Livewire;
use App\Models\Post;
use Livewire\Component;
use Livewire\WithPagination;
class PostForm extends Component
{
use WithPagination;
public $title;
public $description;
public $post_id;
protected $rules = [
'title' => 'required',
'description' => 'required',
];
public function storePost()
{
$this->validate();
$post = Post::create([
'title' => $this->title,
'description' => $this->description
]);
$this->reset();
}
public function edit($id)
{
$post = Post::find($id);
$this->post_id = $post->id;
$this->title = $post->title;
$this->description = $post->description;
}
public function update()
{
$post = Post::updateOrCreate(
[
'id' => $this->post_id,
],
[
'title' => $this->title,
'description' => $this->description
],
);
$this->reset();
}
public function destroy($id)
{
Post::destroy($id);
}
public function render()
{
return view('livewire.post-form', ['posts' => Post::latest()->paginate(10)]);
}
}
resources/views/livewire/post-form.blade.php
<div>
<h4 class="mb-4 text-2xl font-bold">Post </h4>
<div>
<div class="container mx-auto">
<form method="POST" wire:submit.prevent="storePost">
@csrf
<div>
<label for="title">Title</label>
<input type="text" wire:model.lazy="title" class="w-full py-2 rounded">
@error('title')
<span class="text-red-600">{{ $message }}</span>
@enderror
</div>
<div class="mt-8">
<label class="block mb-2 text-xl">Description </label>
<textarea wire:model.lazy="description" rows="3" cols="20" class="w-full rounded">
</textarea>
@error('description')
<span class="text-red-600">{{ $message }}</span>
@enderror
</div>
<button type="submit" class="px-4 py-2 mt-4 text-white bg-blue-600 rounded">
Submit
</button>
<button type="submit" wire:click="update" class="px-4 py-2 text-white bg-indigo-600 rounded">
Update
</button>
</form>
</div>
<div class="flex flex-col mt-8">
<div class="py-2">
<div
class="min-w-full border-b border-gray-200 shadow">
<table class="min-w-full">
<thead>
<tr>
<th class="px-6 py-3 text-left text-gray-500 border-b border-gray-200 bg-gray-50">
Id
</th>
<th class="px-6 py-3 text-left text-gray-500 border-b border-gray-200 bg-gray-50">
Title
</th>
<th class="px-6 py-3 text-left text-gray-500 border-b border-gray-200 bg-gray-50">
Edit
</th>
<th class="px-6 py-3 text-left text-gray-500 border-b border-gray-200 bg-gray-50">
Delete
</th>
</tr>
</thead>
<tbody class="bg-white">
@foreach($posts as $post)
<tr>
<td class="px-6 py-4 border-b border-gray-200">
<div class="flex items-center">
<div class="ml-4">
<div class="text-sm text-gray-900">
{{ $post->id }}
</div>
</div>
</div>
</td>
<td class="px-6 py-4 border-b border-gray-200">
<div class="text-sm text-gray-900">
{{ $post->title }}
</div>
</td>
<td class="px-6 py-4 border-b border-gray-200">
<button wire:click="edit({{ $post->id }})" class="px-4 py-2 text-white bg-blue-600">
Edit
</button>
</td>
<td class="px-6 py-4 text-sm text-gray-500 border-b border-gray-200">
<button wire:click="destroy({{ $post->id }})"
class="px-4 py-2 text-white bg-red-600">
Delete
</button>
</td>
</tr>
@endforeach
</tbody>
</table>
</div>
{{ $posts->links() }}
</div>
</div>
</div>
</div>