Build a CRUD Application Using Laravel and Vue

Build a CRUD Application Using Laravel and Vue


In this tutorial, we’ll build a complete CRUD application using VueJS and Laravel.
For illustration, consider the following simple app:

CRUD VueJS & Laravel

Contents

Before we kick off

Learn Vue.js and modern, cutting-edge front-end technologies from core-team members and industry experts with our premium tutorials and video courses on VueSchool.io.

Click here to Browse all Courses on VueSchool.io

prerequisites

  • We have a text editor
  • Composer running on your computer
  • Have basic knowledge of Laravel and VueJs.

Introduction

CRUD is an acronym for the four basic operations: Create, Read, Update, Delete. Most applications have some kind of CRUD functionality, and we can assume that every programmer had to deal with CRUD at some point. A CRUD application is one that uses forms to get data into and out of a database.

Setting up Laravel and VueJs

We first need to setup Laravel. For that, create a project named vue_laravel.

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

Laravel UI provides a way to install bootstrap, vue, and react setup. If you want to install VueJS in your laravel project, install the following laravel UI composer package.

composer require laravel/ui

Now we’re ready to install VueJs.

php artisan ui vue

Suppose you would like to install Vue with the auth run the following command. But it is no need for our example.

php artisan ui vue --auth

So now, please run the command below to compile your fresh scaffolding.

npm install

Open your /resources/js/app.js , and you’ll see the Vue starter code. All the VueJs part we’ll write in this file app.js

require('./bootstrap');

window.Vue = require('vue');

Vue.component('example-component', require('./components/ExampleComponent.vue').default);

const app = new Vue({
    el: '#app',
});

To ensure that Webpack will automatically recompile your assets when it detects a change run this command:

npm run watch

In case you want to go deeper in Laravel Mix, click here to get it done, using the official documentation.

We need to create the controller, model, the table to save the store the data, and the routes. For that, run the following commands:

Controller:

php artisan make:controller CarsController

Model:

php artisan make:model Cars

In cars.php file paste this:

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Cars extends Model
{
    protected $table = "cars";
    public $timestamps = true;

    protected $fillable = [
		'make','model'
	];
}

Make sure you have your Laravel project connected to your database.

Migration:

php artisan make:migration create_cars_table

Migrate it!

php artisan migrate

Update your routes. Add this code in your route file /routes/web.php:

Route::post('/storeCar','CarsController@storeCar');
Route::get('/getCars', 'CarsController@getCars');
Route::post('/deleteCar/{id}', 'CarsController@deleteCar');
Route::post('/editCars/{id}', 'CarsController@editCar');

We are ready to go. Now you can run the app and start coding.

php artisan serve

Initialize VueJS

In the app.js you can see that we have an idd named #app. It means that all the Vue part is handled in an element with an id app.

const app = new Vue({
    el: '#app',
});

That’s why all the HTML content is wrapped in an element with id app. Open the welcome.blade.php file and initialize Vue.

   <body>

            <div id="app">
                ...
            </div>
       
    </body>

Create Operation

Let’s create a quick bootstrap form to handle this operation. Inside of div element paste this code:

<div class="title m-b-md">
    Car
</div>
<div class="alert alert-danger" role="alert" v-bind:class="{hidden: hasError}">
    All fields are required!
</div>
<div class="form-group">
    <label for="make">Make</label>
    <input type="text" class="form-control" id="make" required placeholder="Make" name="make" v-model="newCar.make">
</div>
                                        
<div class="form-group">
    <label for="model">Model</label>
    <input type="text" class="form-control" id="model" required placeholder="Model" name="model" v-model="newCar.model">
</div>

<button class="btn btn-primary" @click.prevent="createCar()">
    Add Car
</button>

In above snippet we have:

  • An alert block that will display a message whenever fields are empty. The display block is controlled by hasError variable that is declared in app.js.
  • Form Input Bindings
  • For button, we use @click.prevent="createCar()" which calls createCar Vue method that is declared in app.js.

So in the vue, we need to initialize the variables that we’ll need for this operation.

data: {
        newCar: {'make': '', 'model': ''},
        hasError: true,
        cars: [],
     }

We use the function below to insert data into the database, and we also check if the fields are empty.

        createCar: function createCar() {
            var input = this.newCar;
            var _this = this;
            if(input['make'] == '' || input['model'] == '') {
                this.hasError = false;
            }
            else {
                this.hasError= true;
                axios.post('/storeCar', input).then(function(response){
                    _this.newCar = {'make': '', 'model': ''}
                    _this.getCars();
                }).catch(error=>{
                    console.log("Insert: "+error);
                });
            }
        },

In CarsController /app/Http/Controllers/CarsController.php add this function:

    public function storeCar(Request $request) {
        $car = new Cars();
        $car->make = $request->make;
        $car->model = $request->model;
        $car->save();

        return $car;
    }

Read Operation

To get all the data we need to create a function named getCars() in our app.js file.

        getCars: function getCars(){
            var _this = this;
            axios.get('/getCars').then(function(response){
                _this.cars = response.data;
            }).catch(error=>{
                console.log("Get All: "+error);
            });
        },

Let’s update our controller to fetch the data (CarsController.php):

    public function getCars(Request $request) {
        $cars = Cars::all();

        return $cars;
    }

We would like to call the getCars() function when the page loads. To do so, there is a hook in vue called mounted. In this hook, we call the method getCars():

app.js

    mounted: function mounted(){
        this.getCars();
    },

To display these data we need to add a table in our view /resources/view/welcome.blade.php.

<table class="table table-striped" id="table">
                    <thead>
                        <tr>
                        <th scope="col">#</th>
                        <th scope="col">Make</th>
                        <th scope="col">Model</th>
                        <th scope="col">Actions</th>
                        </tr>
                    </thead>
                    <tbody>
                        <tr v-for ="car in cars">
                        <th scope="row">@{{car.id}}</th>
                        <td>@{{car.make}}</td>
                        <td>@{{car.model}}</td>

                        <td @click="setVal(car.id, car.make, car.model)"  class="btn btn-info" class="btn btn-info btn-lg" data-toggle="modal" data-target="#myModal"><i class="fa fa-pencil"></i>
                        </td>
                        <td  @click.prevent="deleteCar(car)" class="btn btn-danger"> 
                        <i class="fa fa-trash"></i>
                        </td>
                        </tr>
                    </tbody>
                </table>

Now the data is set in the variable cars, so iterating with v-for this variable shows us all the data we need for the view.

Update Operation

In our table we have two buttons in each row: “delete” and “edit”.

When edit button is clicked, a modal is shown with that particular row’s data and an option to edit them. We can use the Bootstrap modal.

<!-- Modal -->
   <div id="myModal" class="modal fade" role="dialog">
     ...
   </div>

We need these fields to display the data we want to edit:

<div class="modal-body">
    <input type="hidden" disabled class="form-control" id="e_id" name="id" required :value="this.e_id">
        Make: <input type="text" class="form-control" id="e_make" name="make" required :value="this.e_make">
        Model: <input type="text" class="form-control" id="e_model" name="model" required  :value="this.e_model">
</div>    
                        
<div class="modal-footer">
    <button type="button" class="btn btn-primary" @click="editCar()">Save changes</button>
    <button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
</div>

After showing the model, the setVal method is set. We use this function to display the data in our model.

To work with this function, first we need to add this variables in our vue file (app.js):

        e_id: '',
        e_make: '',
        e_model: '',

And setup the setVal function:

setVal(val_id, val_make, val_model) {
   this.e_id = val_id;
   this.e_make = val_make;
   this.e_model = val_model;
 },

Now we can use these variables in our model.

In our modal footer, you can see that we have two buttons. One to edit and the other one to close the model.

Open app.js and create the function to edit the data.

        editCar: function(){
            var _this = this;
            var id_val_1 = document.getElementById('e_id');
            var make_val_1 = document.getElementById('e_make');
            var model_val_1 = document.getElementById('e_model');
            var model = document.getElementById('myModal').value;
             axios.post('/editCars/' + id_val_1.value, {val_1: make_val_1.value, val_2: model_val_1.value})
               .then(response => {
                 _this.getCars();
               });
     },

And do not forget to update our CarsController.php.  This snippet will fetch the row with the given id, and update its elements make, and model.

    public  function editCar(Request $request, $id){
        $car = Cars::where('id',$id)->first();

        $car->make = $request->get('val_1');
        $car->model = $request->get('val_2');
        $car->save();

        return $car;
    }

Delete Operation

On each row we see the icon to delete an item. So when clicked it calls deleteCar() function.

app.js

deleteCar: function deleteCar(car) {
  var _this = this;
  axios.post('/deleteCar/' + car.id).then(function(response){
   _this.getCars();
      }).catch(error=>{
            console.log("Delete car: "+error);
            });
        },

We need to update the CarsController.php:

    public function deleteCar(Request $request){
        $car = Cars::find($request->id)->delete();
    }

Conclusion

You probably notice that in every function, we use _this.getCars(). This is to update the UI after data changes.

Now you can use the CRUD operations for your needs. you can Check out CodeSource here.

Thanks for reading.


Share on social media

//