Creating a CRUD (Create, Read, Update, Delete) application using Laravel 11 with Inertia.js and Vue.js involves several steps. Here's a detailed example to help you set up and implement this functionality.
### Step 1: Set Up Laravel Project
Start by creating a new Laravel project if you haven't already:
```bash
composer create-project --prefer-dist laravel/laravel laravel-inertia-crud
cd laravel-inertia-crud
```
### Step 2: Install Inertia.js
Next, install Inertia.js and the required packages for Vue.js:
```bash
composer require inertiajs/inertia-laravel
npm install @inertiajs/inertia @inertiajs/inertia-vue3 @vitejs/plugin-vue vue
```
### Step 3: Set Up Vite for Vue.js
Ensure that Vite is properly set up to work with Vue.js. Update `vite.config.js`:
```javascript
import { defineConfig } from 'vite';
import laravel from 'laravel-vite-plugin';
import vue from '@vitejs/plugin-vue';
export default defineConfig({
plugins: [
laravel({
input: 'resources/js/app.js',
refresh: true,
}),
vue(),
],
});
```
Next, update your `resources/js/app.js`:
```javascript
import { createApp, h } from 'vue';
import { createInertiaApp } from '@inertiajs/inertia-vue3';
import { resolvePageComponent } from 'laravel-vite-plugin/inertia-helpers';
createInertiaApp({
resolve: name => resolvePageComponent(`./Pages/${name}.vue`, import.meta.glob('./Pages/**/*.vue')),
setup({ el, App, props, plugin }) {
createApp({ render: () => h(App, props) })
.use(plugin)
.mount(el);
},
});
```
### Step 4: Create Database and Migrate
Set up your database in the `.env` file:
```env
DB_DATABASE=laravel_inertia_crud
DB_USERNAME=root
DB_PASSWORD=
```
Run the migrations to set up the database:
```bash
php artisan migrate
```
### Step 5: Create a Model, Migration, and Controller
Create a model and migration for the entity you'll be working with, such as `Post`:
```bash
php artisan make:model Post -m
```
In `database/migrations/{timestamp}_create_posts_table.php`, add the necessary fields:
```php
public function up()
{
Schema::create('posts', function (Blueprint $table) {
$table->id();
$table->string('title');
$table->text('body');
$table->timestamps();
});
}
```
Run the migration:
```bash
php artisan migrate
```
Create a controller for handling the CRUD operations:
```bash
php artisan make:controller PostController
```
In `app/Http/Controllers/PostController.php`, add the following methods for CRUD operations:
```php
namespace App\Http\Controllers;
use App\Models\Post;
use Illuminate\Http\Request;
use Inertia\Inertia;
class PostController extends Controller
{
public function index()
{
$posts = Post::all();
return Inertia::render('Posts/Index', ['posts' => $posts]);
}
public function create()
{
return Inertia::render('Posts/Create');
}
public function store(Request $request)
{
$request->validate([
'title' => 'required|string|max:255',
'body' => 'required',
]);
Post::create($request->all());
return redirect()->route('posts.index')->with('success', 'Post created successfully.');
}
public function edit(Post $post)
{
return Inertia::render('Posts/Edit', ['post' => $post]);
}
public function update(Request $request, Post $post)
{
$request->validate([
'title' => 'required|string|max:255',
'body' => 'required',
]);
$post->update($request->all());
return redirect()->route('posts.index')->with('success', 'Post updated successfully.');
}
public function destroy(Post $post)
{
$post->delete();
return redirect()->route('posts.index')->with('success', 'Post deleted successfully.');
}
}
```
### Step 6: Set Up Routes
Add the routes for the CRUD operations in `routes/web.php`:
```php
use App\Http\Controllers\PostController;
Route::get('/posts', [PostController::class, 'index'])->name('posts.index');
Route::get('/posts/create', [PostController::class, 'create'])->name('posts.create');
Route::post('/posts', [PostController::class, 'store'])->name('posts.store');
Route::get('/posts/{post}/edit', [PostController::class, 'edit'])->name('posts.edit');
Route::put('/posts/{post}', [PostController::class, 'update'])->name('posts.update');
Route::delete('/posts/{post}', [PostController::class, 'destroy'])->name('posts.destroy');
```
### Step 7: Create Vue.js Pages
Create the Vue components for each part of the CRUD application.
#### `resources/js/Pages/Posts/Index.vue`
```vue
<template>
<div>
<h1>Posts</h1>
<div v-if="flash.success" class="alert alert-success">{{ flash.success }}</div>
<a href="/posts/create" class="btn btn-primary">Create New Post</a>
<table class="table">
<thead>
<tr>
<th>Title</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
<tr v-for="post in posts" :key="post.id">
<td>{{ post.title }}</td>
<td>
<a :href="`/posts/${post.id}/edit`" class="btn btn-warning">Edit</a>
<form :action="`/posts/${post.id}`" method="POST" style="display:inline;">
<input type="hidden" name="_method" value="DELETE">
<input type="hidden" name="_token" :value="csrfToken">
<button type="submit" class="btn btn-danger">Delete</button>
</form>
</td>
</tr>
</tbody>
</table>
</div>
</template>
<script>
export default {
props: {
posts: Array,
},
computed: {
csrfToken() {
return document.querySelector('meta[name="csrf-token"]').getAttribute('content');
},
flash() {
return this.$page.props.flash;
},
},
};
</script>
```
#### `resources/js/Pages/Posts/Create.vue`
```vue
<template>
<div>
<h1>Create Post</h1>
<form method="POST" action="/posts">
<input type="hidden" name="_token" :value="csrfToken">
<div class="form-group">
<label for="title">Title</label>
<input type="text" name="title" class="form-control" required>
</div>
<div class="form-group">
<label for="body">Body</label>
<textarea name="body" class="form-control" required></textarea>
</div>
<button type="submit" class="btn btn-primary">Create</button>
</form>
</div>
</template>
<script>
export default {
computed: {
csrfToken() {
return document.querySelector('meta[name="csrf-token"]').getAttribute('content');
},
},
};
</script>
```
#### `resources/js/Pages/Posts/Edit.vue`
```vue
<template>
<div>
<h1>Edit Post</h1>
<form :action="`/posts/${post.id}`" method="POST">
<input type="hidden" name="_method" value="PUT">
<input type="hidden" name="_token" :value="csrfToken">
<div class="form-group">
<label for="title">Title</label>
<input type="text" name="title" class="form-control" :value="post.title" required>
</div>
<div class="form-group">
<label for="body">Body</label>
<textarea name="body" class="form-control" required>{{ post.body }}</textarea>
</div>
<button type="submit" class="btn btn-primary">Update</button>
</form>
</div>
</template>
<script>
export default {
props: {
post: Object,
},
computed: {
csrfToken() {
return document.querySelector('meta[name="csrf-token"]').getAttribute('content');
},
},
};
</script>
```
### Step 8: Run the Application
Run the following commands to compile your assets and start the Laravel server:
```bash
npm install
npm run dev
php artisan serve
```
Visit `http://localhost:8000/posts` to see your Inertia.js + Vue.js CRUD application in action.
### Conclusion
This example provides a basic CRUD application using Laravel 11, Inertia.js, and Vue.js. You can expand upon this by adding more complex validation, authentication, or other features as needed. The combination of Inertia.js and Vue.js offers a powerful way to build dynamic, single-page applications (SPAs) with the familiar Laravel backend.
0 Comments