Laravel 11 Inertia Vue JS CRUD Example Tutorial
In this tutorial, I will you you step by step CRUD Application using Inertia Vue JS. we will use breeze install auth scaffold and vue js setup.
Inertia.js is a framework that allows you to build single-page applications (SPAs) using traditional server-side routing. It lets you use frontend frameworks like React, Vue, or Svelte without the need for a separate API. Instead of returning HTML, the server sends JSON data to the frontend, which Inertia then renders. This setup simplifies development by keeping the server-side and client-side code together, making it easier to manage and maintain your application.
In this example, we will install breeze and create auth scaffolding using Inertia vue js. Then we will create a posts table with title and body fields. We will create a simple CRUD operation of post module using vue js. So let's follow step by step and create a CRUD application with Vue JS.
Preview:
Step for Laravel 11 CRUD using Inertia Vue JS
- Step 1: Install Laravel 11
- Step 2: Create Auth using Breeze
- Step 3: Create Migration and Model
- Step 4: Create PostController File
- Step 5: Create Route
- Step 6: Update Vue Component
- Run Laravel App
Step 1: Install Laravel 11
First of all, we need to get a fresh Laravel 11 version application using the command below because we are starting from scratch. So, open your terminal or command prompt and run the command below:
composer create-project laravel/laravel example-app
Step 2: Create Auth using Breeze
Now, in this step, we need to use the composer command to install breeze, so let's run the below command and install the below library.
composer require laravel/breeze --dev
Now, we need to create authentication using the below command. You can create basic login, register, and email verification.
Now, you need to choose "Vue with Inertia" option.
You can see below commands:
php artisan breeze:install
Now, we need to run the migration command to create the database table.
php artisan migrate
Step 3: Create Migration and Model
Here, we need to create a database migration for the posts table, and also we will create a model for the posts table.
php artisan make:migration create_posts_table
Migration:
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up(): void
{
Schema::create('posts', function (Blueprint $table) {
$table->id();
$table->string('title');
$table->text('body');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down(): void
{
Schema::dropIfExists('posts');
}
};
run migration now:
php artisan migrate
Now we will create a Post model by using the following command:
php artisan make:model Post
App/Models/Post.php
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Post extends Model
{
use HasFactory;
protected $fillable = [
'title', 'body'
];
}
Step 4: Create PostController File
Now, here we will create a PostController using artisan command. So, run the below command to create a Post CRUD application component.
php artisan make:controller PostController
now, let update the following code to the PostCotroller file.
app/Http/Controllers/PostController.php
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Models\Post;
use Inertia\Inertia;
class PostController extends Controller
{
/**
* Write code on Method
*
* @return response()
*/
public function index()
{
$posts = Post::all();
return Inertia::render('Post/Index', ['posts' => $posts]);
}
/**
* Write code on Method
*
* @return response()
*/
public function create()
{
return Inertia::render('Post/Create');
}
/**
* Write code on Method
*
* @return response()
*/
public function store(Request $request)
{
$post = new Post($request->all());
$post->save();
return redirect()->route('posts.index');
}
/**
* Write code on Method
*
* @return response()
*/
public function edit(Post $post)
{
return Inertia::render('Post/Edit', ['post' => $post]);
}
/**
* Write code on Method
*
* @return response()
*/
public function update(Request $request, Post $post)
{
$post->update($request->all());
return redirect()->route('posts.index');
}
/**
* Write code on Method
*
* @return response()
*/
public function destroy(Post $post)
{
$post->delete();
return redirect()->back();
}
}
Step 5: Create Route
In this step, we will create posts resource route in web.php file. so, let's update the file:
routes/web.php
<?php
...
use App\Http\Controllers\PostController;
Route::resource('posts', PostController::class);
Step 6: Update Vue Files
Here, we will update the following list of files for our listing page and create vue component files.
So, let's update all the files as below:
resources/js/Pages/Post/Index.vue
<script setup>
import AuthenticatedLayout from '@/Layouts/AuthenticatedLayout.vue';
import { Head, Link, useForm } from '@inertiajs/vue3';
defineProps({
posts: {
type: Array,
default: () => [],
},
});
const form = useForm({});
const deletePost = (id) => {
form.delete(`posts/${id}`);
};
</script>
<template>
<Head title="Manage Posts" />
<AuthenticatedLayout>
<template #header>
<h2 class="font-semibold text-xl text-gray-800 leading-tight">Manage Posts</h2>
</template>
<div class="py-12">
<div class="max-w-7xl mx-auto sm:px-6 lg:px-8">
<div class="bg-white overflow-hidden shadow-sm sm:rounded-lg">
<div class="p-6 text-gray-900">
<Link href="posts/create"><button class="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded my-3">Create New Post</button></Link>
<table class="table-auto w-full">
<thead>
<tr>
<th class="border px-4 py-2">ID</th>
<th class="border px-4 py-2">Title</th>
<th class="border px-4 py-2">Content</th>
<th class="border px-4 py-2" width="250px">Action</th>
</tr>
</thead>
<tbody>
<tr v-for="post in posts" :key="post.id">
<td class="border px-4 py-2">{{ post.id }}</td>
<td class="border px-4 py-2">{{ post.title }}</td>
<td class="border px-4 py-2">{{ post.body }}</td>
<td class="border px-4 py-2">
<Link :href="`posts/${post.id}/edit`"><button class="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded">Edit</button></Link>
<button class="bg-red-500 hover:bg-red-700 text-white font-bold py-2 px-4 rounded ml-2" @click="deletePost(post.id)">Delete</button>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
</AuthenticatedLayout>
</template>
resources/js/Pages/Post/Create.vue
<script setup>
import AuthenticatedLayout from '@/Layouts/AuthenticatedLayout.vue';
import { useForm, Link } from "@inertiajs/vue3";
const form = useForm({
title: "",
body: "",
});
const submit = () => {
form.post("/posts");
};
</script>
<template>
<Head title="Manage Posts" />
<AuthenticatedLayout>
<template #header>
<h2 class="font-semibold text-xl text-gray-800 leading-tight">Create Post</h2>
</template>
<div class="py-12">
<div class="max-w-7xl mx-auto sm:px-6 lg:px-8">
<div class="bg-white overflow-hidden shadow-sm sm:rounded-lg">
<div class="p-6 text-gray-900">
<Link href="/posts"><button class="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded my-3">Back</button></Link>
<form @submit.prevent="submit">
<div class="mb-4">
<label
for="title"
class="block text-gray-700 text-sm font-bold mb-2">
Title:</label>
<input
type="text"
class="shadow appearance-none border rounded w-full py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:shadow-outline"
placeholder="Enter Title"
id="title"
v-model="form.title" />
</div>
<div class="mb-4">
<label
for="body"
class="block text-gray-700 text-sm font-bold mb-2">
Body:</label>
<textarea
class="shadow appearance-none border rounded w-full py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:shadow-outline" id="body"
v-model="form.body"
placeholder="Enter Body"></textarea>
</div>
<button type="submit" class="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded my-3 text-white">
Submit
</button>
</form>
</div>
</div>
</div>
</div>
</AuthenticatedLayout>
</template>
resources/js/Pages/Post/Edit.vue
<script setup>
import AuthenticatedLayout from '@/Layouts/AuthenticatedLayout.vue';
import { useForm, Link } from "@inertiajs/vue3";
const props = defineProps({
post: {
type: Object,
default: null,
},
});
const form = useForm({
title: props.post.title,
body: props.post.body,
});
const submit = () => {
form.put(`/posts/${props.post.id}`);
};
</script>
<template>
<Head title="Manage Posts" />
<AuthenticatedLayout>
<template #header>
<h2 class="font-semibold text-xl text-gray-800 leading-tight">Edit Post</h2>
</template>
<div class="py-12">
<div class="max-w-7xl mx-auto sm:px-6 lg:px-8">
<div class="bg-white overflow-hidden shadow-sm sm:rounded-lg">
<div class="p-6 text-gray-900">
<Link href="/posts"><button class="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded my-3">Back</button></Link>
<form @submit.prevent="submit">
<div class="mb-4">
<label
for="title"
class="block text-gray-700 text-sm font-bold mb-2">
Title:</label>
<input
type="text"
class="shadow appearance-none border rounded w-full py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:shadow-outline"
placeholder="Enter Title"
id="title"
v-model="form.title" />
</div>
<div class="mb-4">
<label
for="body"
class="block text-gray-700 text-sm font-bold mb-2">
Body:</label>
<textarea
class="shadow appearance-none border rounded w-full py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:shadow-outline" id="body"
v-model="form.body"
placeholder="Enter Body"></textarea>
</div>
<button type="submit" class="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded my-3 text-white">
Submit
</button>
</form>
</div>
</div>
</div>
</div>
</AuthenticatedLayout>
</template>
Now, inside the AuthenticatedLayout file. we need to add link on header for posts page.
resources/js/Layouts/AuthenticatedLayout.vue
<NavLink :href="route('posts.index')" :active="route().current('posts.index')">
Posts
</NavLink>
Run Laravel App:
All the required steps have been done, now you have to type the given below command and hit enter to run the Laravel app:
php artisan serve
Now, we need to build our application using npm command, so run the NPM command:
npm run build
Now, Go to your web browser, type the given URL and view the app output:
http://localhost:8000/
Preview:
List View:
now it works...
I hope it can help you...
Hardik Savani
I'm a full-stack developer, entrepreneur and owner of ItSolutionstuff.com. I live in India and I love to write tutorials and tips that can help to other artisan. I am a big fan of PHP, Laravel, Angular, Vue, Node, Javascript, JQuery, Codeigniter and Bootstrap from the early stage. I believe in Hardworking and Consistency.
We are Recommending you
- Laravel 11 Reverb Real-Time Notifications Example
- Laravel 11 Send Email with Attachment Example
- How to Generate Thumbnail Image in Laravel 11?
- Laravel 11 Add or Remove Multiple Input Fields with jQuery Example
- Laravel 11 MongoDB CRUD Application Tutorial
- Laravel 11 Real-Time Notifications using Pusher Example
- Laravel 11 Send Email Via Notification Example
- Laravel 11 JSON Web Token(JWT) API Authentication Tutorial
- Laravel 11 Create Blade File using Command Example
- Laravel 11 Livewire CRUD using Jetstream & Tailwind CSS
- Laravel 11 CRUD with Image Upload Tutorial
- Laravel 11 Ajax CRUD Operation Tutorial Example
- Laravel 11 CRUD Application Example Tutorial