Complete Laravel 8 Vue JS CRUD Tutorial

Share this Article
Reading Time: 14 minutes
8,270 Views

Vue js is a javascript framework which mainly used for frontend of any application. Laravel by default configured to accept vue js.

Inside this article we will see the complete concept of Laravel 8 Vue Js crud application. That will be a single page application.

You also like these article of Vue Js with Laravel 8 –

To do for this tutorial –

  • Laravel application setup with Vue
  • API Setup in Laravel
  • CRUD – List Students, Add Student, Update Student, Delete Student

Let’s get started.


Installation of Laravel Application

Laravel Installation can be done in two ways.

  • Laravel Installer
  • By using composer

Laravel Installer

To install Laravel via Laravel installer, we need to install it’s installer first. We need to make use of composer for that.

$ composer global require laravel/installer

This command will install laravel installer at system. This installation is at global scope, so you type command from any directory at terminal. To verify type the given command –

$ laravel

This command will open a command palette of Laravel Installer.

To create ad install laravel project in system,

$ laravel new blog

With the name of blog a laravel project will be created at your specified path.

By using composer

Alternatively, we can also install Laravel by Composer command create-project. If your system doesn’t has Composer Installed, Learn Composer Installation Steps. Here is the complete command to create a laravel project-

$ composer create-project --prefer-dist laravel/laravel blog

After following these steps we can install a Laravel application into system.

To start the development server of Laravel –

$ php artisan serve

This command outputs –

Starting Laravel development server: http://127.0.0.1:8000

Assuming laravel already installed at system.


Create Database & Connect

To create a database, either we can create via Manual tool of PhpMyadmin or by means of a mysql command.

CREATE DATABASE laravel_app;

To connect database with application, Open .env file from application root. Search for DB_ and update your details.

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=laravel_app
DB_USERNAME=root
DB_PASSWORD=root

Installation of vue, vue-router NPM Package

Open project into terminal and run this npm command to install vue package.

$ npm install vue vue-router vue-axios

It will install all vue packages and adds into dev dependency.

Open package.json file, look into it. vue should be added into at dependecies.

"dependencies": {
        "vue": "^2.6.12",
        "vue-axios": "^3.2.4",
        "vue-router": "^3.5.1"
 }

Run NPM Installer

$ npm install

It will installs all npm dependencies.


Update ‘webpack’ Mix File

Webpack file is used to compile, bootstrap application and save into /public/js folder i.e app.js. Open webpack.mix.js file from application root. You need to add something here.

Initial code,

//...

mix.js('resources/js/app.js', 'public/js').vue()
    .postCss('resources/css/app.css', 'public/css', [
        //
]);

Update to,

mix.js('resources/js/app.js', 'public/js').vue()
    .postCss('resources/css/app.css', 'public/css', [
        //
]);

You will see, we have added .vue() into code.

If you miss to add it, you will get error something like this when you compile your application.

  • Original file linked with Vue js – /resources/js/app.js
  • Compiled file running with application – /public/js/app.js

Create Model & Migration

Open project into terminal and run this artisan command.

$ php artisan make:model Student -m

It will create a Model file along with a migration.

  • Student.php model file at /app/Models folder.
  • 2021_05_12_161643_create_students_table.php migration file at /database/migrations folder.

Open Student.php and write this complete code into it.

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class Student extends Model
{
    use HasFactory;

    protected $fillable = [
        'name',
        'email',
        'mobile',
        'gender'
    ];
}

Open 2021_05_12_161643_create_students_table.php migration and write this complete code into it.

<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

class CreateStudentsTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('students', function (Blueprint $table) {
            $table->id();
            $table->string("name", 120);
            $table->string("email", 120);
            $table->string("mobile", 20)->nullable();
            $table->enum("gender", ["male", "female", "other"]);
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('students');
    }
}

Run Migration

Next, we need to create tables inside database.

$ php artisan migrate

This command will create tables inside database.


Create Controller

Next, we need to create a controller file.

$ php artisan make:controller StudentController

It will create a file StudentController.php at /app/Http/Controllers folder.

Open StudentController.php and write this complete code into it.

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Models\Student;

class StudentController extends Controller
{
    public function index()
    {
        $students = Student::all()->toArray();
        return array_reverse($students);      
    }

    public function store(Request $request)
    {
        $student = new Student([
            'name' => $request->input('name'),
            'email' => $request->input('email'),
            'mobile' => $request->input('mobile'),
            'gender' => $request->input('gender')
        ]);
        $student->save();

        return response()->json('Student created successfully!');
    }

    public function show($id)
    {
        $student = Student::find($id);
        return response()->json($student);
    }

    public function update($id, Request $request)
    {
        $student = Student::find($id);
        $student->update($request->all());

        return response()->json('Student data updated successfully!');
    }

    public function destroy($id)
    {
        $student = Student::find($id);
        $student->delete();

        return response()->json('Student deleted successfully!');
    }
}

Application Routes Setup

Next, we need to set application routes.

Open web.php from /routes folder.

//...

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

Now, we need to set API routes. APIs will be used by vue js crud app.

Create Vue Js CRUD APIs

Open api.php from /routes folder.

# Add this to head
use App\Http\Controllers\StudentController;

//...
Route::middleware('api')->group(function () {
    Route::resource('students', StudentController::class);
});

To see all the available routes of this application, open terminal and type this command –

$ php artisan route:list

You should see like this –


Create Blade Layout File

Go to /resources/views folder and create a folder name layouts.

Inside this folder create a file name app.blade.php.

Open app.blade.php and write this complete code into it.

<!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() }}" />
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css"><link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css">

    <title>Vue JS CRUD Operations in Laravel 8 Tutorial</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>

Create Vue Resource Files

We will create routes, components etc.

Main Component & Routes

Go to /resources/js folder.

  • App.vue
  • routes.js

Create these files with name App.vue and routes.js

Open App.vue and write this complete code into it.

<template>
    <div class="container"> 

        <router-view> </router-view>
        
    </div>
</template>
 
<script>
    export default {}
</script>

Open routes.js file and write this complete code.

import Students from './components/Students.vue';
import AddStudent from './components/AddStudent.vue';
import UpdateStudent from './components/UpdateStudent.vue';

export const routes = [{
        name: 'home',
        path: '/',
        component: Students
    },
    {
        name: 'add',
        path: '/add',
        component: AddStudent
    },
    {
        name: 'edit',
        path: '/edit/:id',
        component: UpdateStudent
    }
];

Now, we need vue components for CRUD operation.

Create a components folder inside /resources/js folder

Inside this components folder, we will create these files –

  • AddStudent.vue
  • Students.vue
  • UpdateStudent.vue

Open AddStudent.vue and write this complete code into it.

<template>
  <div>
    <div class="container">
      <h2>Add Student</h2>
      <div class="panel panel-primary">
        <div class="panel-heading">
            Add Student
            <router-link to="/" class="btn btn-info pull-right" style="margin-top:-7px;margin-left:2px;">Student List</router-link>
        </div>
        <div class="panel-body">
          <form @submit.prevent="addStudent">
            <div class="form-group">
              <label>Name</label>
              <input type="text" class="form-control" v-model="student.name" />
            </div>
            <div class="form-group">
              <label>Email</label>
              <input
                type="email"
                class="form-control"
                v-model="student.email"
              />
            </div>
            <div class="form-group">
              <label>Mobile</label>
              <input
                type="text"
                class="form-control"
                v-model="student.mobile"
              />
            </div>
            <div class="form-group">
              <label>Gender</label>
              <select class="form-control" v-model="student.gender">
                <option value="">Select gender</option>
                <option value="male">Male</option>
                <option value="female">Female</option>
                <option value="other">Other</option>
              </select>
            </div>

            <button type="submit" class="btn btn-primary">Add</button>
          </form>
        </div>
      </div>
    </div>
  </div>
</template>
 
<script>
export default {
  data() {
    return {
      student: {},
    };
  },
  methods: {
    addStudent() {
      this.axios
        .post("http://localhost:8000/api/students", this.student)
        .then((response) => this.$router.push({ name: "home" }))
        .catch((err) => console.log(err))
        .finally(() => (this.loading = false));
    },
  },
};
</script>

Open Students.vue and write this complete code into it.

<template>
  <div>
    <div class="container">
      <h2>Students</h2>
      <div class="panel panel-primary">
        <div class="panel-heading">
            Students
            <router-link to="/add" class="btn btn-info pull-right" style="margin-top:-7px;margin-left:2px;">Add Student</router-link>
        </div>
        <div class="panel-body">
          <table class="table">
            <thead>
              <tr>
                <th>ID</th>
                <th>Name</th>
                <th>Email</th>
                <th>Mobile</th>
                <th>Gender</th>
                <th>Actions</th>
              </tr>
            </thead>
            <tbody>
              <tr v-for="student in students" :key="student.id">
                <td>{{ student.id }}</td>
                <td>{{ student.name }}</td>
                <td>{{ student.email }}</td>
                <td>{{ student.mobile }}</td>
                <td>{{ student.gender }}</td>
                <td>
                  <div class="btn-group" role="group">
                    <router-link
                      :to="{ name: 'edit', params: { id: student.id } }"
                      class="btn btn-success"
                      >Edit</router-link
                    >
                    <button
                      class="btn btn-danger"
                      @click="deleteStudent(student.id)"
                    >
                      Delete
                    </button>
                  </div>
                </td>
              </tr>
            </tbody>
          </table>
        </div>
      </div>
    </div>
  </div>
</template>
 
<script>
export default {
  data() {
    return {
      students: [],
    };
  },
  created() {
    this.axios.get("http://localhost:8000/api/students").then((response) => {
      this.students = response.data;
    });
  },
  methods: {
    deleteStudent(id) {
      this.axios
        .delete(`http://localhost:8000/api/students/${id}`)
        .then((response) => {
          let i = this.students.map((data) => data.id).indexOf(id);
          this.students.splice(i, 1);
        });
    },
  },
};
</script>
                

Open UpdateStudent.vue and write this complete code into it.

<template>
  <div>
    <div class="container">
      <h2>Update Student</h2>
      <div class="panel panel-primary">
        <div class="panel-heading">
            Update Student
            <router-link to="/" class="btn btn-info pull-right" style="margin-top:-7px;margin-left:2px;">Student List</router-link>
        </div>
        <div class="panel-body">
          <form @submit.prevent="updateStudent">
            <div class="form-group">
              <label>Name</label>
              <input type="text" class="form-control" v-model="student.name" />
            </div>
            <div class="form-group">
              <label>Email</label>
              <input
                type="email"
                class="form-control"
                v-model="student.email"
              />
            </div>
            <div class="form-group">
              <label>Mobile</label>
              <input
                type="text"
                class="form-control"
                v-model="student.mobile"
              />
            </div>
            <div class="form-group">
              <label>Gender</label>
              <select class="form-control" v-model="student.gender">
                <option value="">Select gender</option>
                <option value="male">Male</option>
                <option value="female">Female</option>
                <option value="other">Other</option>
              </select>
            </div>

            <button type="submit" class="btn btn-primary">Add</button>
          </form>
        </div>
      </div>
    </div>
  </div>
</template>
 
<script>
export default {
  data() {
    return {
      student: {},
    };
  },
  created() {
    this.axios
      .get(`http://localhost:8000/api/students/${this.$route.params.id}`)
      .then((res) => {
        this.student = res.data;
      });
  },
  methods: {
    updateStudent() {
      this.axios
        .patch(
          `http://localhost:8000/api/students/${this.$route.params.id}`,
          this.student
        )
        .then((res) => {
          this.$router.push({ name: "home" });
        });
    },
  },
};
</script>
           

We have completed the basic file settings that we need for Vue Js CRUD.


Loading Vue Application Files

Open app.js from /resources/js folder. Write this complete code into it.

require('./bootstrap');

import Vue from 'vue'

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),
});

Bootstrap & Compile Application

Open project into terminal and run this command.

$ npm run dev

Application will be compiled and save it to app.js of public folder.


Application Testing

Open project to terminal and type the command to start development server

$ php artisan serve

URL – http://127.0.0.1:8000/add

Add Student

Click on Student List Button

Update Student Page

We hope this article helped you to learn Complete Laravel 8 Vue JS CRUD Tutorial in a very detailed way.

If you liked this article, then please subscribe to our YouTube Channel for PHP & it’s framework, WordPress, Node Js video tutorials. You can also find us on Twitter and Facebook.

Find More on Laravel 8 Articles here