Loading...
+880 1736 699819 Mon - Sat: 9:00 AM - 8:00 PM
Follow us:
Home Blog Article
Blog

Laravel & Vue.js 3 Product Create Tutorial (API Based)

Laravel & Vue.js 3 Product Create Tutorial (API Based)

Building modern web applications requires a powerful backend and a reactive frontend. This Laravel & Vue.js 3 product create tutorial - API based explains how to build a real-world product creation system using Laravel REST API and Vue.js 3.

This tutorial follows a clean API-based architecture, making it ideal for scalable enterprise applications.


Laravel Backend

Create Product Migration Product Table

php artisan make:migration create_products_table

// database/migrations/xxxx_xx_xx_create_products_table.php Schema::create('products', function (Blueprint $table) { $table->id(); $table->string('name'); $table->string('sku')->unique(); $table->decimal('price', 10, 2); $table->integer('stock')->default(0); $table->text('description')->nullable(); $table->string('image')->nullable(); $table->timestamps(); });
php artisan migrate

Create Product Model

php artisan make:model Product


// app/Models/Product.php

class Product extends Model
{
    protected $fillable = [
        'name',
        'sku',
        'price',
        'stock',
        'description',
        'image'
    ];
}

Create Product Controller

php artisan make:controller Api/ProductController


// app/Http/Controllers/Api/ProductController.php

use App\Models\Product;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Storage;

class ProductController extends Controller
{
    public function store(Request $request)
    {
        $validated = $request->validate([
            'name'        => 'required|string|max:255',
            'sku'         => 'required|unique:products,sku',
            'price'       => 'required|numeric',
            'stock'       => 'required|integer',
            'description' => 'nullable|string',
            'image'       => 'nullable|image|mimes:jpg,png,jpeg|max:2048'
        ]);

        if ($request->hasFile('image')) {
            $validated['image'] = $request->file('image')
                ->store('products', 'public');
        }

        $product = Product::create($validated);

        return response()->json([
            'message' => 'Product created successfully',
            'data'    => $product
        ], 201);
    }
}

API Route

// routes/api.php

use App\Http\Controllers\Api\ProductController;

Route::post('/products', [ProductController::class, 'store']);

php artisan storage:link

Vue.js 3 Frontend

Axios Setup

npm install axios

// src/services/api.js import axios from 'axios' export default axios.create({ baseURL: 'http://localhost:8000/api', headers: { 'Accept': 'application/json' } })

Product Create Component

<!-- src/views/ProductCreate.vue -->

<template>
  <div class="max-w-xl mx-auto p-6">
    <h2 class="text-xl font-bold mb-4">Create Product</h2>

    <form @submit.prevent="submit">
      <input v-model="form.name" placeholder="Product Name" class="input" />

      <input v-model="form.sku" placeholder="SKU" class="input" />

      <input type="number" v-model="form.price" placeholder="Price" class="input" />

      <input type="number" v-model="form.stock" placeholder="Stock" class="input" />

      <textarea v-model="form.description" placeholder="Description" class="input"></textarea>

      <input type="file" @change="handleFile" />

      <button class="btn">Save Product</button>
    </form>

    <p v-if="error" class="text-red-500 mt-2">{{ error }}</p>
  </div>
</template>

<script setup>
import { reactive, ref } from 'vue'
import api from '@/services/api'

const error = ref(null)

const form = reactive({
  name: '',
  sku: '',
  price: '',
  stock: '',
  description: '',
  image: null
})

const handleFile = (e) => {
  form.image = e.target.files[0]
}

const submit = async () => {
  error.value = null

  const data = new FormData()
  Object.keys(form).forEach(key => {
    data.append(key, form[key])
  })

  try {
    await api.post('/products', data, {
      headers: { 'Content-Type': 'multipart/form-data' }
    })

    alert('Product Created Successfully')
  } catch (err) {
    error.value = err.response?.data?.message || 'Something went wrong'
  }
}
</script>

Vue Router

// src/router/index.js

{
  path: '/products/create',
  component: () => import('@/views/ProductCreate.vue')
}


Tags: Blog
Share this post

Encoderbase Team

Author

Articles and insights from the Encoderbase editorial team covering web development, software engineering, and digital solutions.

Enjoyed this article?

Get more articles like this delivered to your inbox — no spam, unsubscribe any time.

Link copied to clipboard!