Tutorial Laravel 12 dan Nuxt JS #12 Membuat Halaman Edit dalam Nuxt JS SSR dengan Laravel 12 API

Tutorial ini membahas integrasi lengkap antara Laravel 12 sebagai backend API dan Nuxt JS 4 sebagai frontend modern berbasis Vue 3. Cocok untuk pemula yang ingin membangun aplikasi fullstack SPA (Single Page Application) dengan REST API, dan SSR (Server Side Rendering).

✅ Telah dilihat 1142 kali

Rating: 5.00 ⭐

... 24 July 2025, 11:08

Membuat Halaman Edit Produk di Nuxt 4 (SSR) dengan Laravel 12 sebagai API

Untuk melengkapi fitur manajemen produk, kita juga perlu menambahkan halaman edit produk. Halaman ini memungkinkan pengguna untuk memperbarui data produk yang sudah ada melalui antarmuka Nuxt 4, dengan data yang disimpan di backend Laravel 12.

Silakan teman-teman buat sebuah folder baru di dalam direktori pages/product dengan nama edit. Setelah itu, di dalam folder edit tersebut, buatlah sebuah file baru bernama [id].vue.

Struktur folder dan file-nya akan terlihat seperti berikut:

pages/
└── product/
  └── edit/
      └── [id].vue

Penjelasan

Penamaan file [id].vue menggunakan dynamic route milik Nuxt, yang artinya file ini akan menangani URL seperti /product/edit/1, /product/edit/42, dan sebagainya, sesuai dengan id produk yang ingin diedit.

Dengan pendekatan ini, kita dapat:

  • Mengambil data produk berdasarkan ID yang diterima dari URL.

  • Menampilkan data tersebut dalam form.

  • Memperbarui data melalui API Laravel dengan metode PUT atau PATCH.

Silakan buka file [id].vue kemudian masukkan baris kode berikut ini:

<template>
<div class="min-h-screen bg-gradient-to-br from-blue-100 via-white to-blue-100 py-10">
  <h1 class="text-3xl font-bold text-gray-800 mb-6 text-center">Edit Produk</h1>

  <form @submit.prevent="submitProduct" class="max-w-lg mx-auto bg-white p-6 rounded-lg shadow-md">
    <div v-if="loading" class="text-center text-gray-500">Loading...</div>
    <div v-else-if="error" class="text-center text-red-500">{{ error }}</div>
    <div v-else>
      <div class="mb-4">
        <label class="block text-gray-700 font-medium mb-1">Nama Produk</label>
        <input v-model="product.name" type="text" class="w-full p-2 border rounded-lg" required />
      </div>
 
      <div class="mb-4">
        <label class="block text-gray-700 font-medium mb-1">Harga</label>
        <input v-model="product.price" type="number" class="w-full p-2 border rounded-lg" required />
      </div>
 
      <div class="mb-4">
        <label class="block text-gray-700 font-medium mb-1">Deskripsi</label>
        <textarea v-model="product.description" class="w-full p-2 border rounded-lg" required></textarea>
      </div>
 
      <div class="mb-4">
        <label class="block text-gray-700 font-medium mb-1">Stok</label>
        <input v-model="product.stock" type="number" class="w-full p-2 border rounded-lg" required />
      </div>
 
      <div class="flex justify-between">
        <NuxtLink to="/products" class="bg-gray-400 text-white px-4 py-2 rounded-lg hover:bg-gray-500 transition">
          Kembali
        </NuxtLink>
        <button type="submit" class="bg-blue-500 text-white px-4 py-2 rounded-lg hover:bg-blue-600 transition">
          Simpan Perubahan
        </button>
      </div>
    </div>
  </form>
</div>
</template>

<script setup>
import { ref, onMounted } from "vue";
import { useRouter, useRoute } from "vue-router";
import { useHead } from '#imports'

const { fetchProductById, updateProduct } = useProducts();
useHead({
title: "Edit Produk | Toko Online Lagikoding",
meta: [
  {
    name: "description",
    content: "Edit data produk terbaik dengan harga terbaik di toko online kami.",
  },
],
});
const router = useRouter();
const route = useRoute();

const product = ref({
name: "",
price: "",
description: "",
stock: "",
});

const loading = ref(false);
const error = ref(null);

const loadProduct = async () => {
try {
loading.value = true;
const response = await fetchProductById(route.params.id);
product.value = response.data;
} catch (err) {
error.value = "Gagal memuat data produk.";
} finally {
loading.value = false;
}
};

const submitProduct = async () => {
try {
await updateProduct(route.params.id, product.value);
alert("Produk berhasil diperbarui!");
router.push("/products");
} catch (err) {
alert("Gagal memperbarui produk. Silakan coba lagi.");
}
};

onMounted(loadProduct);
</script>

Tampilan Antarmuka (Template)

Pada blok <template>, kita menyusun sebuah halaman dengan tampilan sederhana namun informatif:

  • Judul Halaman Menggunakan elemen <h1> di tengah halaman untuk memberikan konteks bahwa pengguna sedang berada di halaman edit produk.

  • Formulir Edit Produk Form ini terdiri dari beberapa input field yang telah di-binding menggunakan v-model ke data produk, meliputi:

    • Nama Produk

    • Harga

    • Deskripsi

    • Stok

  • Penanganan State Ada tiga kondisi utama yang kita tangani:

    • loading → saat data produk sedang diambil dari server.

    • error → jika terjadi kesalahan saat mengambil data.

    • data tampil → saat data berhasil dimuat.

  • Navigasi dan Submit Terdapat dua tombol di bagian bawah form:

    • Kembali: kembali ke halaman daftar produk.

    • Simpan Perubahan: memicu proses pengiriman data edit ke server.

Script dan Logika Vue

Beberapa hal penting yang dilakukan dalam blok <script setup>:

  • Import & Setup Kita menggunakan beberapa fitur dari Vue dan Nuxt:

    • ref dan onMounted dari Vue untuk state dan lifecycle hook.

    • useRouter dan useRoute dari Vue Router untuk navigasi dan mengambil id dari URL.

    • useHead dari Nuxt untuk mengatur meta tag halaman.

  • Fungsi loadProduct() Fungsi ini dijalankan saat komponen dimount. Ia bertugas mengambil data produk berdasarkan id dari URL, dan mengisi state product agar field input dapat menampilkan data awal.

  • Fungsi submitProduct() Fungsi ini akan dijalankan saat form disubmit. Ia akan:

    • Mengirim data baru ke server menggunakan fungsi updateProduct.

    • Menampilkan notifikasi keberhasilan (menggunakan alert).

    • Mengarahkan pengguna kembali ke halaman daftar produk (/products).

Composable useProducts()

Kode ini mengasumsikan bahwa Anda sudah memiliki sebuah composable bernama useProducts yang menyediakan fungsi:

  • fetchProductById(id) → untuk mengambil detail produk berdasarkan ID.

  • updateProduct(id, data) → untuk memperbarui data produk.


Npm Run Dev

Silakan teman-teman janlankan perintah npm run dev dan juga php artisan serve untuk laravel API nya. Maka berikut tampilan ketika kita akses halaman aplikasi kita pada url http://localhost:3000/product/edit/id_produk

Sampai pada materi kali ini, kita telah berhasil menyelesaikan seluruh fitur CRUD dasar dalam pembuatan aplikasi web, dengan Nuxt.js sebagai frontend (SSR) dan Laravel 12 sebagai backend API-nya.

Melalui serangkaian langkah yang telah kita lalui, mulai dari menampilkan daftar produk, menambahkan data baru, mengedit, hingga menghapus produk — kita telah membangun fondasi yang solid untuk pengembangan aplikasi berbasis API yang lebih kompleks ke depannya.

🔥 Flash Sale


📜 Table Of Contents


📌 Daftar Episode


Daftar eBook