Laravel 8 Vue JS File/Image Upload Example Tutorial: Build File Upload in Laravel 8 Vue JS App

Last updated on by Digamber

Throughout this comprehensive tutorial, you will learn how to create file or image upload functionality in Laravel 8 and Vue JS web application; you will se how to use Axios in laravel vue to make an HTTP request to upload a file object in the database.

File uploading is a standard programming task, without which application development is not imaginable. Moreover, file uploading is also a part of our life, and we propel tons of files, images on social media platforms. Generically, our most common tasks include uploading images and files on Facebook, instagram, and Twitter. This tutorial will help you understand the nitty-gritty of file uploading in the laravel vue js application from scratch.

Vue.js is a powerful and developer-friendly open-source model–view–ViewModel front end JavaScript framework for creating immaculate user interfaces or commonly known SPA (single-page applications).

Laravel 8 Vue JS File/Image Upload Example

Uploading files via laravel api will become an easy task for you; after completing this tutorial, you will be able to create a laravel app, create routes, create a controller.

Laravel Axios file upload example will help you make HTTP requests to upload files, install NPM modules in the laravel vue app, set up vue in laravel, and create a blade view to understand the concepts of how to display uploaded file in laravel vue.

Install Laravel App

In this first step, you have to use the following command to create a new laravel project:

composer create-project laravel/laravel laravel-vue-file-upload-example --prefer-dist

Connecting to Database

Get into laravel project root, open .env file and update the database configuration details as given below:

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

Model and Migration

Further, create a file model, it will create a new table inside the database:

php artisan make:model FileUpload -m

Define code in database/migrations/create_file_uploads_table.php:

<?php

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

class CreateFileUploadsTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('file_uploads', function (Blueprint $table) {
            $table->id();
            $table->string('name')->nullable();
            $table->string('path')->nullable();            
            $table->timestamps();
        });
    }

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

Add code as given below in app/Models/FileUpload.php:

<?php

namespace App\Models;

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

class FileUpload extends Model
{
    use HasFactory;
    protected $fillable = [
        'name',
        'path'
    ];    
}

Finally invoke the database migration:

php artisan migrate

Install Laravel Vue UI and NPM Dependencies

Open console, run the following command to install laravel Vue UI:

composer require laravel/ui

Use command to install Vue components:

php artisan ui vue

Next, install run below command to compile scaffolding:

npm install

Create Controller

In this step you have to generate a file uploading controller:

php artisan make:controller FileController

Add following code in app\Http\Controllers\FileController.php:

<?php

namespace App\Http\Controllers;

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

class FileController extends Controller
{
      public function index(){
        return view('welcome');
      }
    
      public function upload(Request $request){
            
            $request->validate([
               'file' => 'required|mimes:jpg,jpeg,png,csv,txt,xlx,xls,pdf|max:2048'
            ]);
    
            $fileUpload = new FileUpload;
    
            if($request->file()) {
                $file_name = time().'_'.$request->file->getClientOriginalName();
                $file_path = $request->file('file')->storeAs('uploads', $file_name, 'public');
    
                $fileUpload->name = time().'_'.$request->file->getClientOriginalName();
                $fileUpload->path = '/storage/' . $file_path;
                $fileUpload->save();
    
                return response()->json(['success'=>'File uploaded successfully.']);
            }
       }
}

Create Routes

Define following code in routes/web.php file to create routes:

<?php

use Illuminate\Support\Facades\Route;
use App\Http\Controllers\FileController;

/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| contains the "web" middleware group. Now create something great!
|
*/

Route::get('/', [FileController::class, 'index']);

Route::post('/upload', [FileController::class, 'upload'])->name('upload');

Set Up Vue Component

Move to resources/js/components/ directory, inside here create FileUploadComponent.vue file.

Next, add the following code in resources/js/components/FileUploadComponent.vue:

<template>
    <div class="container">
        <div class="row justify-content-center">
            <div class="col-md-8">
                <div class="card">
                    <div class="card-header">Laravel Vue JS File Upload Demo</div>

                    <div class="card-body">

                        <div v-if="success != ''" class="alert alert-success">
                            {{success}}
                        </div>

                        <form @submit="formSubmit" enctype="multipart/form-data">
                            <input type="file" class="form-control" v-on:change="onChange">
                            <button class="btn btn-primary btn-block">Upload</button>
                        </form>
                    </div>
                </div>
            </div>
        </div>
    </div>
</template>

<script>
    export default {
        data() {
            return {
                name: '',
                file: '',
                success: ''
            };
        },
        methods: {
            onChange(e) {
                this.file = e.target.files[0];
            },
            formSubmit(e) {
                e.preventDefault();
                let existingObj = this;

                const config = {
                    headers: {
                        'content-type': 'multipart/form-data'
                    }
                }

                let data = new FormData();
                data.append('file', this.file);

                axios.post('/upload', data, config)
                    .then(function (res) {
                        existingObj.success = res.data.success;
                    })
                    .catch(function (err) {
                        existingObj.output = err;
                    });
            }
        }
    }

</script>

Then, register the Vue component inside the resources/js/app.js:

require('./bootstrap');

window.Vue = require('vue');

Vue.component('file-upload-component', require('./components/FileUploadComponent.vue').default);

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

Go to resources/views/ folder and create layout directory and app.blade.php file.

Thereafter, add the below code in resources/views/layout/app.blade.php:

<!doctype html>
<html>
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta name="csrf-token" content="{{ csrf_token() }}">
 
    <title>Laravel Vue JS File Upload Example</title>
 
    <script src="{{ asset('js/app.js') }}" defer></script>
    <link href="{{ asset('css/app.css') }}" rel="stylesheet">
 
</head>
<body>
    <div id="app">
 
        <main class="py-4">
            @yield('content')
        </main>
 
    </div>
</body>
</html>

Next you have to place the vue file upload component in resources/views/welcome.blade.php file:

@extends('layout.app')

@section('content')
<div class="container">
    <div class="row justify-content-center">
         
        <div class="col-md-8">
            <div class="card">
            
                <div class="card-body">
                  <file-upload-component></file-upload-component>
                </div>
                 
            </div>
        </div>
    </div>
</div>
@endsection

Ultimately, you have to open the console and run the node development server:

npm run watch

Open another console as well and start the laravel development server:

php artisan serve

Here is the owl carousel slider integration example in Laravel and Vue js application:

http://127.0.0.1:8000

Laravel Vue JS File/Image Upload Example

Conclusion

The Laravel 8 Vue JS File or Image upload example tutorial is over, i hope this tutorial has given you immense knowledge of file uploading in the laravel vue app also understand the concept of vue Axios file upload.