Complete Laravel 8 Vue JS CRUD Tutorial

Share this Article
Reading Time: 14 minutes
18,221 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.


Laravel Installation

We will create laravel project using composer. So, please make sure your system should have composer installed. If not, may be this article will help you to Install composer in system.

Here is the command to create a laravel project-

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

To start the development server of Laravel –

$ php artisan serve

URL: http://127.0.0.1:8000

Assuming laravel already installed inside your 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')
    .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.

Was this post helpful?

PHP Web Development Courses on Offer in just $4
PHP Web Development Courses on Offer in just $4