Laravel file upload with vue.js & quickadminpanel
Efficient file uploads are essential for modern web applications, enhancing user experience and functionality. In this tutorial, we'll build a robust Laravel file upload API with Vue.js integration using QuickAdminPanel, focusing on progress tracking and efficient handling.
By leveraging Vue.js for the front end and Laravel's powerful back end, we'll create a seamless file upload system complete with a progress bar and validation. QuickAdminPanel will streamline our development process, allowing us to focus on core features.
Prerequisites
To follow along with this tutorial, you should have:
- Basic knowledge of Laravel, PHP, and Vue.js
- Composer installed on your machine
- Node.js and npm installed
- An account with QuickAdminPanel
Setting up a new laravel project with quickadminpanel
First, we'll use QuickAdminPanel to generate a Laravel project with a built-in admin panel.
- Sign in to your QuickAdminPanel account.
- Create a new project and select "Standard Laravel" as the project type.
- Add necessary modules like Users management if needed.
- Download the generated Laravel project.
Unzip the project and navigate to the project directory:
cd your-project-directory
Install the dependencies:
composer install
npm install
Set up your .env
file by copying the .env.example
:
cp .env.example .env
Generate an application key:
php artisan key:generate
Run migrations:
php artisan migrate
Start the development server:
php artisan serve
Implementing a file upload API in laravel
We'll create an API endpoint to handle file uploads.
First, create a new controller:
php artisan make:controller API/FileUploadController
In app/Http/Controllers/API/FileUploadController.php
, update the controller:
<?php
namespace App\Http\Controllers\API;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
class FileUploadController extends Controller
{
public function upload(Request $request)
{
$request->validate([
'file' => 'required|file|max:10240', // Max 10MB
]);
if ($request->file('file')->isValid()) {
$path = $request->file('file')->store('uploads');
return response()->json([
'message' => 'File uploaded successfully.',
'path' => $path,
], 200);
}
return response()->json([
'message' => 'File upload failed.',
], 500);
}
}
Next, add the route to routes/api.php
:
Route::post('/upload', [App\Http\Controllers\API\FileUploadController::class, 'upload']);
Integrating vue.js for front-end file management
Our Laravel project already includes Vue.js, thanks to QuickAdminPanel. Let's create a Vue component for handling file uploads.
First, create a new Vue component:
Create a file resources/js/components/FileUpload.vue
:
<template>
<div>
<input type="file" @change="selectFile" />
<button @click="uploadFile" :disabled="!file">Upload</button>
<div v-if="progress > 0">
<progress :value="progress" max="100"></progress>
<span>{{ progress }}%</span>
</div>
<div v-if="message">
<p>{{ message }}</p>
</div>
</div>
</template>
<script>
export default {
data() {
return {
file: null,
progress: 0,
message: '',
}
},
methods: {
selectFile(event) {
this.file = event.target.files[0]
},
uploadFile() {
if (!this.file) return
let formData = new FormData()
formData.append('file', this.file)
axios
.post('/api/upload', formData, {
headers: {
'Content-Type': 'multipart/form-data',
},
onUploadProgress: (progressEvent) => {
this.progress = Math.round((progressEvent.loaded * 100) / progressEvent.total)
},
})
.then((response) => {
this.message = response.data.message
this.file = null
this.progress = 0
})
.catch((error) => {
console.error(error)
this.message = 'File upload failed.'
this.progress = 0
})
},
},
}
</script>
Update your resources/js/app.js
to register the component:
require('./bootstrap')
window.Vue = require('vue').default
Vue.component('file-upload', require('./components/FileUpload.vue').default)
const app = new Vue({
el: '#app',
})
Compile your assets:
npm run dev
Displaying a progress bar for file uploads
The onUploadProgress
event in axios allows us to track the upload progress, updating the progress
bar accordingly.
In the Vue component, this code manages the progress:
onUploadProgress: (progressEvent) => {
this.progress = Math.round(
(progressEvent.loaded * 100) / progressEvent.total
);
},
Adding the component to your view
Let's add the file-upload
component to one of our views. For example, in
resources/views/home.blade.php
:
@extends('layouts.app')
@section('content')
<div class="container">
<h1>File Upload</h1>
<file-upload></file-upload>
</div>
@endsection
Best practices for handling large file uploads in laravel
When handling large file uploads, consider the following best practices:
- Increase
upload_max_filesize
andpost_max_size
in yourphp.ini
:
upload_max_filesize = 20M
post_max_size = 25M
- Adjust the
client_max_body_size
if using Nginx:
client_max_body_size 25M;
- Implement Chunked Uploads: For extremely large files, consider using chunked uploads to upload files in smaller pieces.
Troubleshooting common file upload issues
- File Not Uploading: Ensure your API endpoint is correctly defined and that the route is accessible.
- Progress Bar Not Updating: Check that the
onUploadProgress
function is correctly implemented in your axios request. - CORS Errors: If you're making API requests to a different domain, ensure that your server is configured to handle CORS.
Conclusion
By integrating Vue.js with Laravel using QuickAdminPanel, we've created a robust file upload system complete with progress tracking and validation. This setup enhances user experience and leverages the strengths of both the front-end and back-end frameworks.
For more advanced features like resumable uploads and cross-browser compatibility, consider integrating an open-source solution like Uppy, which offers a rich set of features and can be easily integrated with Laravel.