Laravel 11 Inertia Vue JS CRUD Example Tutorial


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.

Post a Comment

0 Comments