Laravel Vue JS CRUD Example With File Upload and Pagination

In this tutorial i am going to create Laravel and Vue js crud tutorial with pagination. We will create a Single Page Application(SPA) using the Laravel and Vue.js with image upload. This tutorial you will learn how to use vue router and v-form package to create laravel vue js crud. I will also show you how you can use image Intervention and upload image using vue js in laravel.

In Todays, Most popular JS Framework are React JS and Vue JS. Angular JS and Vue JS are a very user friendly JS Framework and most popular. It provides to manage whole project or application without refresh page and powerful jquery validation.

In this post i going to lean how to create CRUD(Create, Read, Update and Delete) application with pagination using Laravel 6. you can implement crud application from scratch, so no worry if you can implement through bellow simple step. After create successful example, you will find layout as bellow:

Preview: Upload Table

laravel-vue-js-crud-with-image-upload-with-pagination

Preview: Add Upload Modal

laravel-vue-js-crud-with-image-upload-with-pagination-preview

Preview: Error message before submit non-validate data

laravel-vue-js-crud-with-image-upload-with-pagination-preview-with-error-message

Step 1: Laravel Installation

In first step, If you haven't installed Laravel in your system then you have to run bellow command and get fresh Laravel project.

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

Step 2: Create Upload table and model

Run below command to create model and its corresponding table

php artisan make:model Upload -m

In this step i will use Upload model and uploads table to create vue js laravel crup single page application. So paste this below code to your uploads table.

Schema::create('uploads', function (Blueprint $table) {
    $table->bigIncrements('id');
    $table->string('name');
    $table->string('photo');
    $table->timestamps();
});

After create "uploads" table you should setup Upload model for uploads, paste this following code to Upload model.

app/Upload.php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Upload extends Model
{
    protected $guarded = [];
}

Now run migration command after setup your database. 

Step 3: Define the API routes

Now, we need to define the API routes inside the routes >> api.php file.

routes/api.php

//Vue js Api Route

Route::apiResources(
	[
		'photo' => 'API\PhotoController'
	]
);

Step 4: Create Controller

To quickly generate an API resource controller that does not include the create or edit methods, use the --api switch when executing the make:controller command:

php artisan make:controller API/PhotoController --api

Ok, now we have created new controller as UserController in this path app/Http/Controllers/API/PhotoController.php. this controller will manage all route method:

Step 5 : Install Vue dependency and edit configurations

Now, go inside the project folder and install the frontend dependencies using the following command.

Read also : User Roles and Permissions Tutorial in Laravel without Packages

npm install

Now run following command, you can visit vue official documentation

npm install vue-router

Now we have to install v-form for client side validation. Read their documentation to learn more how to use it and how v-form works.

npm i axios vform

Now run this command to install laravel vue pagination package

npm install laravel-vue-pagination

Now we have to install image intervention for vue js image upload.

composer.phar require intervention/image

Now your composer.json has been updated automatically and you're able to require the just created vendor/autoload.php file to PSR-4 autoload the library.

Intervention Image has optional support for Laravel and comes with a Service Provider and Facades for easy integration. The vendor/autoload.php is included by Laravel, so you don't have to require or autoload manually. Just see the instructions below.

After you have installed Intervention Image, open your Laravel config file config/app.php and add the following lines.

In the $providers array add the service providers for this package.

Intervention\Image\ImageServiceProvider::class

Add the facade of this package to the $aliases array.

'Image' => Intervention\Image\Facades\Image::class

Now the Image Class will be auto-loaded by Laravel.

Configu Image Intervention

By default Intervention Image uses PHP's GD library extension to process all images. If you want to switch to Imagick, you can pull a configuration file into your application by running one of the following artisan command.

Publish configuration in Laravel

php artisan vendor:publish --provider="Intervention\Image\ImageServiceProviderLaravelRecent"

In recent Laravel applications the configuration file is copied to config/image.php.

Step 6: Setup app.js file

resources/js/app.js

require('./bootstrap');

window.Vue = require('vue');

//Import View Router
import VueRouter from 'vue-router'
Vue.use(VueRouter)

//Pagination laravel-vue-pagination
Vue.component('pagination', require('laravel-vue-pagination'));

//Import Sweetalert2
import Swal from 'sweetalert2'
window.Swal = Swal
const Toast = Swal.mixin({
  toast: true,
  position: 'top-end',
  showConfirmButton: false,
  timer: 3000,
  timerProgressBar: true,
  onOpen: (toast) => {
    toast.addEventListener('mouseenter', Swal.stopTimer)
    toast.addEventListener('mouseleave', Swal.resumeTimer)
  }
})
window.Toast = Toast

//Import v-from
import { Form, HasError, AlertError } from 'vform'
window.Form = Form;
Vue.component(HasError.name, HasError)
Vue.component(AlertError.name, AlertError)


//Routes
import { routes } from './routes';

//Register Routes
const router = new VueRouter({
    routes, 
    mode: 'hash',

})

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

Read also : Laravel 6 Ajax Form Submit With jQuery Validation

resources/js/routes.js

import Upload from './components/admin/UploadComponent.vue'

export const routes = [
   
    { 
        path:'/upload',
        component:Upload
    },
 
];


Step 7:  Setup Controller

app\Http\Controllers\API\PhotoController.php

namespace App\Http\Controllers\API;

use App\Http\Controllers\Controller;
use App\Upload;
use Illuminate\Http\Request;

class PhotoController extends Controller
{

    public function index()
    {
        return Upload::latest()->paginate(1);
    }

    public function store(Request $request)
    {
        $this->validate($request,[
            'name' => 'required|string|max:191',
            'photo' => 'required'
        ]);

        if($request->photo){

            $name = time().'.' . explode('/', explode(':', substr($request->photo, 0, strpos($request->photo, ';')))[1])[1];
            \Image::make($request->photo)->save(public_path('img/profile/').$name);
            $request->merge(['photo' => $name]);
           
        }

        Upload::create($request->all());

        return ['message' => 'Success'];

    }

    public function show($id)
    {
        //
    }

    public function update(Request $request, $id)
    {
        $upload = Upload::find($id);

        $this->validate($request,[
            'name' => 'required|string|max:191',
            'photo' => 'required'
        ]);

        $currentPhoto = $upload->photo;

        if($request->photo != $currentPhoto){

            $name = time().'.' . explode('/', explode(':', substr($request->photo, 0, strpos($request->photo, ';')))[1])[1];
            \Image::make($request->photo)->save(public_path('img/profile/').$name);
            $request->merge(['photo' => $name]);

            $userPhoto = public_path('img/profile/').$currentPhoto;

            if(file_exists($userPhoto)){

                @unlink($userPhoto);
                
            }
           
        }

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

        return ['message' => 'Success'];
    }

    public function destroy($id)
    {
        $upload = Upload::findOrFail($id);

        $upload->delete();

        $currentPhoto = $upload->photo;

        $userPhoto = public_path('img/profile/').$currentPhoto;

        if(file_exists($userPhoto)) {

            @unlink($userPhoto);
                
        }

        return [
         'message' => 'Photo deleted successfully'
        ];
    }
}

Step 8: Create Blade File

In this step we have to create only one blade file that will manage create, update and delete operation of items module with vue js.

resources/views/master.blade.php

resources/assets/js/components/admin/UploadComponent.vue

Now every thing is done. Now you are ready to check it.

//run this command to compile our all js file
npm run watch

Hope it will be helpful for you. Feel free to ask question if you face any issues.

A web enthusiastic, self-motivated Full-Stack Web Developer from Dhaka, Bangladesh with experience in developing applications using JavaScript, Laravel & Wordpress specifically. Facebook Github Website