Laravel Vue 3 File Uploading with Progress Bar using Vite Example

Hello dev, Today we are going to learn Laravel Vue 3 File Uploading with Progress Bar using Vite Example. This tutorial will cover how you can create a laravel application with vue 3 to upload a file with progress bar using Vite JS.

We are going to use laravel breeze, inertia js, vite and tailwind css to create Laravel Vue 3 File Uploading with Progress Bar Example. The upload of file will be save to the database within files table with name.

What is Vite?

Vite is a modern frontend build tool that provides an extremely fast development environment and bundles your code for production. When building applications with Laravel, you will typically use Vite to bundle your application’s CSS and JavaScript files into production ready assets.

What is Vue JS?

Vue.js is an open-source model–view–view model front end JavaScript framework for building user interfaces and single-page applications. It was created by Evan You, and is maintained by him and the rest of the active core team members.

Also Read: Laravel 9 Vue JS CRUD App using Vite Example

Steps for Laravel Vue 3 File Uploading with Progress Bar using Vite Example:

  • Step 1: Installing a fresh new Laravel 9 Application
  • Step 2: Creating Database and Configuration
  • Step 3: Creating Auth with Breeze
  • Step 4: Creating Migration and Model
  • Step 5: Creating Routes
  • Step 6: Creating Controller
  • Step 7: Creating Vue Page
  • Step 8: Testing
  • Step 9: Conclusion

Step 1: Installing a fresh new Laravel 9 Application

First, we are installing a fresh new laravel 9 application. To install a laravel application run the following command in terminal.

composer create-project laravel/laravel vuejs-upload-vite

cd vuejs-upload-vite

Note: “vuejs-upload-vite” is our laravel application name.

Installing a fresh new Laravel 9 Application
Installing a fresh new Laravel 9 Application

Step 2: Creating Database and Configuration

Now, we will create a database. First open phpmyadmin and create a database with name “vuejs-upload-vite” (you may use anything you like).

Creating Database
Creating Database

Now we are going to add the database details to the laravel application. Open .env file and enter the database details.

Database Configuration in laravel .env file
Database Configuration in laravel .env file

Also Read: Laravel 9 Livewire Multi Step Form Wizard Tutorial

Step 3: Creating Auth with Breeze

Now we are going to create auth with breeze. Run the following command in terminal to install breeze library.

composer require laravel/breeze --dev

create authentication with the following command.

php artisan breeze:install vue

Install Node JS package.

npm install

Now run the vite command and make it keep running.

npm run dev

Note: If error occurs then updated node to v16.16.0 and it worked

Now open new terminal and run the migration.

php artisan migrate

Also Read: Laravel 9 Livewire Datatables Example

Step 4: Creating Migration and Model

Here, We are going to create a migration for Files table. To create a files migration run the following command.

php artisan make:migration create_files_table

add the following fields to files migration file.

<?php

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

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

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

Run the migration again to create files table.

php artisan migrate

So now, We will create File model. To create a File model run the following command in terminal.

php artisan make:model File

And add the following code to File.php model.

<?php

namespace App\Models;

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

class File extends Model
{
    use HasFactory;

    /**
     * The attributes that are mass assignable.
     *
     * @var array
     */
    protected $fillable = [
        'title', 'name'
    ];
  
    /**
     * Get the user's first name.
     *
     * @return \Illuminate\Database\Eloquent\Casts\Attribute
     */
    protected function name(): Attribute
    {
        return Attribute::make(
            get: fn ($value) => url('uploads/'.$value),
        );
    }
}
Creating File Model
Creating File Model

Also Read: Install NextUI with React Js in Laravel 9

Step 5: Creating Routes

Now, We are going to create a routes for our application. Add the following two routes to routes/web.php

<?php

use Illuminate\Foundation\Application;
use Illuminate\Support\Facades\Route;
use Inertia\Inertia;
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('/', function () {
    return Inertia::render('Welcome', [
        'canLogin' => Route::has('login'),
        'canRegister' => Route::has('register'),
        'laravelVersion' => Application::VERSION,
        'phpVersion' => PHP_VERSION,
    ]);
});

Route::get('/dashboard', function () {
    return Inertia::render('Dashboard');
})->middleware(['auth', 'verified'])->name('dashboard');

require __DIR__.'/auth.php';

Route::get('file-upload', [FileController::class, 'index'])->name('file.upload');
Route::post('file-upload', [FileController::class, 'store'])->name('file.upload.store');
Creating Route for our application - Laravel Vue 3 File Uploading with Progress Bar using Vite Example
Creating Route for our application

Step 6: Creating Controller

In this step, we are going to create a File Controller. Create a new file FileController.php in app/Http/Controllers folder and add the following code inside.

app/Http/Controllers/FileController.php

<?php
 
namespace App\Http\Controllers;
 
use Illuminate\Http\Request;
use Inertia\Inertia;
use Illuminate\Support\Facades\Validator;
use App\Models\File;
 
class FileController extends Controller
{
    /**
     * Show the form for creating a new resource.
     *
     * @return Response
     */
    public function index()
    {
        $files = File::latest()->get();
        return Inertia::render('FileUpload', compact('files'));
    }
  
    /**
     * Show the form for creating a new resource.
     *
     * @return Response
     */
    public function store(Request $request)
    {
        Validator::make($request->all(), [
            'title' => ['required'],
            'file' => ['required'],
        ])->validate();
  
        $fileName = time().'.'.$request->file->extension();  
        $request->file->move(public_path('uploads'), $fileName);
    
        File::create([
            'title' => $request->title,
            'name' => $fileName
        ]);
    
        return redirect()->route('file.upload');
    }
}
Creating File Controller - Laravel Vue 3 File Uploading with Progress Bar using Vite Example
Creating File Controller

Also Read: Laravel 9 Install Vue JS Example

Step 7: Creating Vue Page

In this last step we are create a Vue Js Pages for File Upload.

Create a new file FileUpload.vue inside resources/js/Pages and add the following code.

resources/js/Pages/FileUpload.vue

<script setup>
import BreezeAuthenticatedLayout from '@/Layouts/Authenticated.vue';
import BreezeLabel from '@/Components/Label.vue';
import BreezeInput from '@/Components/Input.vue';
import { Head, Link, useForm } from '@inertiajs/inertia-vue3';
defineProps({
    files: Array,
});
const form = useForm({
    title: '',
    file: null
});
const submit = () => {
    form.post(route('file.upload.store'));
};
</script>
<template>
    <Head title="Dashboard" />
    <BreezeAuthenticatedLayout>
        <template #header>
            <h2 class="font-semibold text-xl text-gray-800 leading-tight">
                Laravel Vue 3 Image Upload Example with Vite - Mywebtuts.com
            </h2>
        </template>
        <div class="py-12">
            <div class="max-w-7xl mx-auto sm:px-6 lg:px-8">
                <div class="bg-white overflow-hidden shadow-sm sm:rounded-lg">
                    <div class="p-6 bg-white border-b border-gray-200">
                        <form name="createForm" @submit.prevent="submit">
                                <div className="flex flex-col">
                                    <div className="mb-4">
                                        <BreezeLabel for="title" value="Title" />
                                        
                                        <BreezeInput 
                                            id="title" 
                                            type="text" 
                                            class="mt-1 block w-full" 
                                            v-model="form.title" 
                                            autofocus />
                                        <span className="text-red-600" v-if="form.errors.title">
                                            {{ form.errors.file }}
                                        </span>
                                    </div>
                                    <div className="mb-4">
                                        <BreezeLabel for="file" value="File" />
                                        
                                        <BreezeInput 
                                            id="file" 
                                            type="file" 
                                            class="mt-1 block w-full" 
                                            @input="form.file = $event.target.files[0]"
                                            autofocus />
                                        <span className="text-red-600" v-if="form.errors.title">
                                            {{ form.errors.file }}
                                        </span>
                                    </div>
                                </div>
                                <div v-if="form.progress" className="w-full bg-gray-200 rounded-full dark:bg-gray-700">
                                    <div className="bg-blue-600 text-xs font-medium text-blue-100 text-center p-0.5 leading-none rounded-full" :width="form.progress.percentage"> {{ form.progress.percentage }}%</div>
                                </div>
  
                                <div className="mt-4">
                                    <button
                                        type="submit"
                                        className="px-6 py-2 font-bold text-white bg-green-500 rounded"
                                    >
                                        Save
                                    </button>
                                </div>
                            </form>
                            <h1>Uploaded File List:</h1>
                            <table className="table-fixed w-full">
                                <thead>
                                    <tr className="bg-gray-100">
                                        <th className="px-4 py-2 w-20">No.</th>
                                        <th className="px-4 py-2">Title</th>
                                        <th className="px-4 py-2">Image</th>
                                    </tr>
                                </thead>
                                <tbody>
                                    <tr v-for="file in files">
                                        <td className="border px-4 py-2">{{ file.id }}</td>
                                        <td className="border px-4 py-2">{{ file.title }}</td>
                                        <td className="border px-4 py-2">
                                            <img :src="file.name" width="200" />
                                        </td>
                                    </tr>
                                </tbody>
                            </table>
                    </div>
                </div>
            </div>
        </div>
    </BreezeAuthenticatedLayout>
</template>
Creating Vue Page - Laravel Vue 3 File Uploading with Progress Bar using Vite Example
Creating Vue Page

Also Read: React JS Image Upload using Vite in Laravel 9 Example

Step 8: Testing

Now let’s test our Laravel 9 Vue JS CRUD App using Vite Example. Run the following command to start laravel server.

php artisan serve

Also run Vite in new terminal and keep it running.

npm run dev

or build.

npm run build

Now open any web browser and enter the following link to test the application.

http://127.0.0.1:8000

Note: Register a new user and then click posts from navigation.

After Login Open following URL:

http://127.0.0.1:8000/file-upload

Preview:

Laravel Vue 3 File Uploading with Progress Bar using Vite Example
Laravel Vue 3 File Uploading with Progress Bar using Vite Example

Step 9: Conclusion

Today, We had learn Laravel Vue 3 File Uploading with Progress Bar using Vite Example. Hope this tutorial helped you with learning Laravel 9. If you have any question you can ask us at comment section below. If you like the tutorial please subscribe our YouTube Channel and follow us on social network Facebook and Instagram.

Also Read: How to Remove a Specific Element From an Array in PHP

6 Comments

Leave a Reply