Laravel 8 Vue js CRUD operation with example

In any web application, CRUD operation is basic functionality to create, read, update and delete data. The way of CRUD method changes from application to application.

In this tutorial article, we will learn how to create CRUD application in Laravel 8 with Vue.js framework. Using frontend Javascript framework, Vue.js, Reactjs in Laravel application provides smooth user experience. We will create application step by step from the scratch.

Follow these steps to create CRUD example in Laravel 8 with Vue.js

  • Step 1: Create a fresh Laravel application
  • Step 2: Configure database connection
  • Step 3: Configure and run migration
  • Step 4: Create new routes
  • Step 5: Create resource controller class
  • Step 6: Install Laravel Vue.js UI
  • Step 7: Create Vue.js main Layout
  • Step 8: Create Vue.js CRUD Components
  • Step 9: Create Vue.js routes and initialize Vue.js app
  • Step 10: Run and test Laravel CRUD operation using Vue.js

Let's start from creating fresh Laravel 8 application

Step 1: Create a fresh Laravel 8 application

In the first step, we will create new Laravel application using Composer command. You can learn How to install Composer in Ubuntu. If you have Composer already installed, open the Terminal and run the below Composer command.

composer create-project laravel/laravel crud --prefer-dist

After the application is created, change the Terminal directory to application root directory.

cd crud

Step 2: Configure database connection

Open the project in your favourite IDE. In this step, we will setup database connection in Laravel application. Laravel database variables are stored in .env file at root of the directory. Open .env file and change database credentials according to your MySQL credentials.

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=vuejs_crud
DB_USERNAME=root
DB_PASSWORD=secret

Step 3: Configure and run migration

We will create CRUD example for users table. Laravel out of the box provides users migration and model. So we don't have to create migration file or Model class. You can create them according to your requirements or use users table. Open migration file at the /database/migrations/2014_10_12_000000_create_users_table.php and modify the table fields according to your requirement. We will keep the as it is to make tutorial simple.

Now run the migrate command to generate database tables.

php artisan migrate

Step 4. Create new routes

We will create one view route for blade view and resource routes for users crud application. Laravel's all routes are located at routes directory. Open routes/web.php file and add new route.

<?php

use Illuminate\Support\Facades\Route;
 
Route::get('{any}', function () {
    return view('layouts.app');
})->where('any', '.*');

And in the routes/api.php file, add below api routes.

<?php

use Illuminate\Support\Facades\Route;
Use App\Http\Controllers\UserController;

Route::resource('users', UserController::class);

Step 5. Create resource controller class

We have created application routes. In this step, we will create resource controller class and add application logic in the methods. Run the below command to create controller.

php artisan make:controller UserController --resource

The resource controller already have below methods defined for different operations.

Method      Url    Action    Route Name
GET       /users    index    users.index
GET      /users/create    create    users.create
POST    /users    store    users.store
GET    /users/{id}    show    users.show
GET     /users/{id}/edit    edit    users.edit
PUT/PATCH    /users/{id}    update    users.update
DELETE    /users/{id}    destroy    users.destroy

We are using Vue.js in frontend, so all methods' response will be sent in json format instead of blade views. Add below code into controller method.

<?php

namespace App\Http\Controllers;

use App\Models\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Hash;

class UserController extends Controller
{
    /**
     * Display a listing of the resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function index()
    {
        $users = User::orderBy('id', 'desc')
            ->get()
            ->toArray();

        return response()->json($users);
    }

    /**
     * Store a newly created resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\Response
     */
    public function store(Request $request)
    {
        User::create([
            'name' => $request->name,
            'email' => $request->email,
            'password' => Hash::make($request->password)
        ]);

        return response()->json('User created successfully.');
    }

    /**
     * Display the specified resource.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function show($id)
    {
        $user = User::find($id);
        
        return response()->json($user);
    }

    /**
     * Show the form for editing the specified resource.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function edit($id)
    {
        //
    }

    /**
     * Update the specified resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function update(Request $request, $id)
    {
        $user = User::find($id);

        $user->update($request->all());

        return response()->json('User updated successfully.');
    }

    /**
     * Remove the specified resource from storage.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function destroy($id)
    {
        $user = User::find($id);
        $user->delete();

        return response()->json('User deleted successfully.');
    }
}

Step 6 : Install Laravel Vue.js UI

Our backend coding is completed, Now we will work on Vue.js. First install Laravel UI using following composer command.

composer require laravel/ui

And set Vue.js in UI using artisan command.

php artisan ui vue

We also need to install vue-router for routing and vue-axios package for request. So install these packages using below npm command. 

npm install vue-router vue-axios

Now install npm packages that requires for front end.

npm install

Now compile the assets using below npm command. This will compile assets automatically everytime when you change in Vue.js code. We will keep this process running. So better to run this command into another Terminal window.

npm run watch

Step 7: Create Vue.js main Layout

In the front end side, we will create common layout blade view at resources/views/layouts/app.blade.php file. This layout view will initiate Vue.js app in root element. Place the below HTML code into this file.

<!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" value="{{ csrf_token() }}" />
        <title>Laravel 8 CRUD Operation using Vue.js</title>
        <link href="{{ mix('css/app.css') }}" type="text/css" rel="stylesheet" />
    </head>
    <body>
        <div id="app"></div>
        <script src="{{ mix('js/app.js') }}" type="text/javascript"></script>
    </body>
</html>

Step 8: Create Vue.js CRUD Components

Now we will create Vue.js templates which will render in the main template file app.blade.php. Vue components are located at resources/js directory. First start with creating main Vue template App.vue file.

<template>
    <div class="container">
        <div class="text-center m-5">
            <span class="lead">Laravel 8 CRUD Operation using Vue.js</span>
        </div>
        <nav class="navbar navbar-expand-lg navbar-light bg-light">
            <div class="collapse navbar-collapse">
                <div class="navbar-nav">
                    <router-link to="/" class="btn btn-primary m-1 nav-link">Users</router-link>
                    <router-link to="/create" class="btn btn-success m-1 nav-link">Add User</router-link>
                </div>
            </div>
        </nav>
        <router-view></router-view>
    </div>
</template>
<script>
    export default {}
</script>

Now we need to create following template files for CRUD operation at resources/js/components directory. Create below files and put the code.

  • UserComponent.vue
  • CreateComponent.vue
  • EditComponent.vue

UserComponent.vue for user listing

<template>
    <div>
        <h2 class="text-center">ALL Users</h2>
        <table class="table table-hover">
            <thead>
                <tr>
                    <th>ID</th>
                    <th>Name</th>
                    <th>Email</th>
                    <th>Actions</th>
                </tr>
            </thead>
            <tbody>
                <tr v-for="user in users" :key="user.id">
                    <td>{{ user.id }}</td>
                    <td>{{ user.name }}</td>
                    <td>{{ user.email }}</td>
                    <td>
                        <div role="group">
                            <router-link :to="{name: 'edit', params: { id: user.id }}" class="btn btn-success m-1">Edit</router-link>
                            <button class="btn btn-danger m-1" @click="deleteUser(user.id)">Delete</button>
                        </div>
                    </td>
                </tr>
            </tbody>
        </table>
    </div>
</template>
<script>
    export default {
        data() {
            return {
                users: []
            }
        },
        created() {
            this.axios
                .get('http://localhost:8000/api/users/')
                .then(response => {
                    this.users = response.data;
                });
        },
        methods: {
            deleteUser(id) {
                this.axios
                    .delete(`http://localhost:8000/api/users/${id}`)
                    .then(response => {
                        let i = this.users.map(data => data.id).indexOf(id);
                        this.users.splice(i, 1)
                    });
            }
        }
    }
</script>

CreateComponent.vue to create new user

<template>
    <div>
        <h3 class="text-center">Create User</h3>
        <div class="row">
            <div class="col-md-6">
                <form @submit.prevent="createUser">
                    <div class="form-group">
                        <label>Name</label>
                        <input type="text" class="form-control" v-model="user.name">
                    </div>
                    <div class="form-group">
                        <label>Email</label>
                        <input type="text" class="form-control" v-model="user.email">
                    </div>
                    <div class="form-group">
                        <label>Password</label>
                        <input type="password" class="form-control" v-model="user.password">
                    </div>
                    <button type="submit" class="btn btn-primary">Create</button>
                </form>
            </div>
        </div>
    </div>
</template>
<script>
    export default {
        data() {
            return {
                user: {}
            }
        },
        methods: {
            createUser() {
                this.axios
                    .post('http://localhost:8000/api/users', this.user)
                    .then(response => (
                        this.$router.push({ name: 'users' })
                    ))
                    .catch(err => console.log(err))
                    .finally(() => this.loading = false)
            }
        }
    }
</script>

EditComponent.vue to update exising user

<template>
    <div>
        <h3 class="text-center">Edit User</h3>
        <div class="row">
            <div class="col-md-6">
                <form @submit.prevent="updateUser">
                    <div class="form-group">
                        <label>Name</label>
                        <input type="text" class="form-control" v-model="user.name">
                    </div>
                    <div class="form-group">
                        <label>Email</label>
                        <input type="text" class="form-control" v-model="user.email">
                    </div>
                    <div class="form-group">
                        <label>Password</label>
                        <input type="password" class="form-control" v-model="user.password">
                    </div>
                    <button type="submit" class="btn btn-primary">Update</button>
                </form>
            </div>
        </div>
    </div>
</template>
<script>
    export default {
        data() {
            return {
                user: {}
            }
        },
        created() {
            this.axios
                .get(`http://localhost:8000/api/users/${this.$route.params.id}`)
                .then((res) => {
                    this.user = res.data;
                });
        },
        methods: {
            updateUser() {
                this.axios
                    .patch(`http://localhost:8000/api/users/${this.$route.params.id}`, this.user)
                    .then((res) => {
                        this.$router.push({ name: 'users' });
                    });
            }
        }
    }
</script>

Step 9: Create Vue.js routes and initialize Vue.js app

We have created Vue.js components files. We need routes which will render template according to url. For that, create routes.js file at resources/js directory.

import UserComponent from './components/UserComponent.vue';
import CreateComponent from './components/CreateComponent.vue';
import EditComponent from './components/EditComponent.vue';
 
export const routes = [
    {
        name: 'users',
        path: '/',
        component: UserComponent
    },
    {
        name: 'create',
        path: '/create',
        component: CreateComponent
    },
    {
        name: 'edit',
        path: '/edit/:id',
        component: EditComponent
    }
];

We already have app.js file at resources/js directory. Remove the default code and change it with below codes. This file will import required modules and initialize Vue.js app at #app from main blade file.

require('./bootstrap');

window.Vue = require('vue').default;

import App from './App.vue';
import VueAxios from 'vue-axios';
import VueRouter from 'vue-router';
import axios from 'axios';
import { routes } from './routes';

Vue.use(VueRouter);
Vue.use(VueAxios, axios);
 
const router = new VueRouter({
    mode: 'history',
    routes: routes
});
 
const app = new Vue({
    el: '#app',
    router: router,
    render: h => h(App),
});

Step 10: Run and test Laravel CRUD operation using Vue.js

Now our coding part is completed. All we have to do is test the application. We need to start Laravel server using php artisan serve command from the Terminal. Make sure npm run watch command is running at another Terminal window, so when you change in Vue.js files, it will automatically compiles changes.

php artisan serve

Now open the Browser and run url http://localhost:8000/. You will see All users list.

Now to try to add new user and edit, delete them. If everything is perfect as per tutorial, you wouldn't get any error. To debug error, open the developer console window.

Conclusion

Finally, we have completed the tutorial. We have learned Laravel 8 CRUD with example using Vue.js. I hope you have enjoyed and understood the article. Thank you for giving time in reading the article.