Laravel 9 Api with Vue 3 Composition Api Image Upload Example

In this tutorial we will see laravel 9 rest api with vue 3 composition api image file upload. In vue 3 file upload we will use axios. Before we start we need to setup laravel api with vue 3.

Laravel 9 Backend Api Connect with Vue 3 Using Axios Example

Laravel 9 Rest Api Image Upload with Validation Example


Create Laravel Project

Install fresh laravel app and connect to database.

composer create-project --prefer-dist laravel/laravel image-upload


Create Image Model and Migration

Run shorthand command to create image modal, migration and controller.

php artisan make:model Image -mc 

images_table.php

public function up()
{
    Schema::create('images', function (Blueprint $table) {
        $table->id();
        $table->string('image');
        $table->timestamps();
    });
}

app/Models/Image.php

<?php

namespace App\Models;

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

class Image extends Model
{
    use HasFactory;
    protected $fillable = [
        'image'
    ];
}


Create Image Api Controller and Route

Create Image Api Controller by running below command.

php artisan make:controller Api/ImageController  


First you need to import Image class and import use Symfony\Component\HttpFoundation\Response;

app/Http/Controllers/Api/ImageController.php

<?php

namespace App\Http\Controllers\Api;

use App\Http\Controllers\Controller;
use App\Models\Image;
use Illuminate\Http\Request;
use Symfony\Component\HttpFoundation\Response;


class ImageController extends Controller
{
    public function imageStore(Request $request)
    {
        $this->validate($request, [
            'image' => 'required|image|mimes:jpg,png,jpeg,gif,svg|max:2048',
        ]);
        $image_path = $request->file('image')->store('image', 'public');

        $data = Image::create([
            'image' => $image_path,
        ]);

        return response($data, Response::HTTP_CREATED);
    }
}


Now you need to set api.php route.

routes/api.php

<?php

use App\Http\Controllers\Api\ImageController;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Route;


Route::post('image',[ImageController::class, 'imageStore']);


Migrate database & Storage links

run migrate database

php artisan migrate

Storage links to public directory.

php artisan storage:link

run the laravel server

php artisan serve


Image Upload with Vue 3 Composition Api Using Laravel REST API

Create vue 3 project.

npm init [email protected]

Select your requirements.

Vue.js - The Progressive JavaScript Framework
 Project name:  frontend
 Add TypeScript?  No / Yes
 Add JSX Support?  No / Yes
 Add Vue Router for Single Page Application development?  No / Yes
 Add Pinia for state management?  No / Yes
 Add Vitest for Unit Testing?  No / Yes
 Add Cypress for both Unit and End-to-End testing?  No / Yes
 Add ESLint for code quality?  No / Yes
 Add Prettier for code formatting?  No / Yes
Scaffolding project in /vue-project/frontend...
Done. Now run:
 cd frontend
 npm install
npm run dev


Install axios In Vue 3

Run below command to install vue-axios

npm i vue-axios

Install Tailwind CSS in Vue 3

How to Install Tailwind CSS in Vue 3

or

Read Tailwind Official Doc

Create image vue router

router/index.js

import { createRouter, createWebHistory } from 'vue-router'
import HomeView from '../views/HomeView.vue'
import Image from '../views/Image.vue'

const router = createRouter({
  history: createWebHistory(import.meta.env.BASE_URL),
  routes: [
    {
      path: '/',
      name: 'home',
      component: HomeView
    },
    {
      path: '/image',
      name: 'image',
      component: Image
    },
    {
      path: '/about',
      name: 'about',
      // route level code-splitting
      // this generates a separate chunk (About.[hash].js) for this route
      // which is lazy-loaded when the route is visited.
      component: () => import('../views/AboutView.vue')
    }
  ]
})

export default router

Vue 3 composition api image upload with axios using laravel api.

views/Image.vue

<script>
import { ref } from 'vue';
import axios from 'axios';
import { useRouter } from 'vue-router';
export default {
  setup() {
    const image = ref('');
    const router = useRouter();

    const onFileChange = (e) => {
      image.value = e.target.files[0];
    };
    const submit = async () => {
      if (!image.value) {
        alert('please fill the filed');
      } else {
        const formdata = new FormData();
        formdata.append('image', image.value);
        await axios.post(
          'http://localhost:8000/api/image',
          formdata
        ).then(() => {
          router.push({
            name: 'name',
          });
        })
        .catch((error) => {
          console.log(error);
        });
      }
    };

    return {submit,onFileChange};
  },
};
</script>
<template>
  <div class="flex items-center justify-center h-screen">
    <div class="w-1/3">
      <form @submit.prevent="submit">
        <div class="mb-4">
          <input
            type="file"
            @change="onFileChange"
            class="block w-full text-sm text-gray-500 file:mr-4 file:py-2 file:px-4 file:rounded-full file:border-0 file:font-semibold file:bg-blue-50 file:text-blue-700 hover:file:bg-blue-100"
          />
        </div>
        <button class="px-6 py-1.5 text-white bg-blue-600" type="submit">
          Button
        </button>
      </form>
    </div>
  </div>
</template>
laravel 9 api with vue 3 composition api image upload

laravel 9 api with vue 3 composition api image upload

Run vue server

npm run dev

Show image

<img :src="`http://localhost:8000/storage/${image.image}`"/>