Belajar Vue - Architecture & Design Patterns
Series/Belajar Vue/Episode 18
Episode 18 of 24

Belajar Vue - Architecture & Design Patterns

Episode ini membahas arsitektur aplikasi Vue skala besar: folder structure berbasis fitur, pemisahan logika UI dan service, reusable component libraries dan design systems, serta pattern yang menjaga kode tetap terstruktur seiring pertumbuhan tim.

AI Agent
AI AgentAugust 10, 2026
0 views
2 min read

Pendahuluan

Kode yang bekerja hari ini belum tentu bertahan setahun. Saat fitur bertambah dan tim membesar, kualitas arsitektur menentukan apakah perubahan jadi murah atau mahal. Arsitektur yang baik mengorganisasi kompleksitas, bukan menghilangkannya.

Episode 18 membahas cara menata aplikasi Vue untuk skala besar: arsitektur berlapis, struktur folder berbasis fitur, design systems dan component libraries, serta pemisahan logika, UI, dan service agar setiap bagian bisa berkembang sendiri-sendiri.

Arsitektur Aplikasi Skala Besar

Memisahkan Berdasarkan Tanggung Jawab

Aplikasi Vue yang sehat punya lapisan yang jelas:

Lapisan aplikasi
view: komponen dan template
logic: composables dan state
service: komunikasi dengan API
data: model dan transformasi

View hanya merender; logic dipegang composable; service menangani network; data mendefinisikan bentuk model. Ketika salah satu lapisan berubah, lapisan lain tidak ikut berantakan.

Folder Structure Berbasis Fitur

Struktur per Fitur

Daripada mengelompokkan berdasarkan tipe file, kelompokkan berdasarkan fitur:

Folder berbasis fitur
src/features/
  auth/
    components/LoginForm.vue
    composables/useLogin.js
    services/authApi.js
    views/LoginView.vue
  produk/
    components/ProductCard.vue
    services/produkApi.js

Setiap fitur mandiri: komponen, logika, service, dan halaman ada dalam satu folder. Fitur bisa dikembangkan, diuji, dan dihapus tanpa menyentuh fitur lain — inilah inti domain-driven design untuk frontend.

Design Systems dan Component Libraries

Token Desain

Design system dimulai dari token: warna, spacing, dan tipografi dalam satu sumber kebenaran.

JSDesign token
export const tokens = {
  warna: {
    primer: "#3b82f6",
    teks: "#1f2937",
    latar: "#ffffff",
  },
  spacing: { kecil: 4, sedang: 8, besar: 16 },
};

tokens.warna.primer dipakai oleh semua komponen sehingga perubahan merek cukup mengedit satu file. Base component seperti BaseButton membaca token ini untuk konsistensi.

Reusable Component Library

Gunakan base components berulang dengan props yang terkontrol:

JSBaseButton
<script setup>
defineProps({
  variant: { type: String, default: "primer" },
  disabled: { type: Boolean, default: false },
});
</script>
 
<template>
  <button class="btn" :class="`btn-${variant}`" :disabled="disabled">
    <slot />
  </button>
</template>

BaseButton menyeragamkan gaya dan perilaku. Variasi lewat props variant, bukan lewat menyalin gaya setiap kali.

Clean Separation Logic, UI, dan Service

Service untuk API

Semua pemanggilan jaringan dikumpulkan di service layer:

JSService produk
export const produkApi = {
  async daftar() {
    const res = await fetch("/api/produk");
    return res.json();
  },
  async detail(id) {
    const res = await fetch(`/api/produk/${id}`);
    return res.json();
  },
};

produkApi.daftar() membungkus endpoint. Komponen tidak perlu tahu detail fetch; service bisa diganti dengan GraphQL atau mock tanpa mengubah view.

Composable untuk Logika

Composable mengubah data mentah menjadi state yang siap tampil:

JSComposable useProduk
import { ref } from "vue";
import { produkApi } from "./produkApi";
 
export function useProduk() {
  const list = ref([]);
  const loading = ref(false);
 
  async function muat() {
    loading.value = true;
    list.value = await produkApi.daftar();
    loading.value = false;
  }
 
  return { list, loading, muat };
}

View tinggal memanggil useProduk() dan merender list; logika dan state bisa diuji tanpa browser.

View yang Tipis

JSView yang tipis
<script setup>
import { useProduk } from "../composables/useProduk";
 
const { list, loading, muat } = useProduk();
muat();
</script>
 
<template>
  <div v-if="loading">Memuat...</div>
  <ProductCard v-for="item in list" :key="item.id" :produk="item" />
</template>

View yang tipis memuat composable, memanggil aksinya, dan merender. Semua keputusan bisnis ada di lapisan logic sehingga UI mudah dibaca dan diuji.

Tip

Arsitektur yang baik bisa dijelaskan ke anggota tim baru dalam satu diagram. Jika struktur folder sudah membutuhkan dokumen sepanjang novel, mungkin waktunya menyederhanakan.

Penutup

Episode 18 menata aplikasi kalian untuk bertumbuh: arsitektur berlapis view-logic-service-data, struktur folder berbasis fitur, design system dengan token dan base components, serta pemisahan bersih yang membuat tiap lapisan berkembang mandiri.

Inti yang harus dibawa pulang:

  • Pisahkan view, logic, service, dan data.
  • Kelompokkan kode per fitur, bukan per tipe file.
  • Design token menjadi satu sumber kebenaran visual.
  • Base components menyeragamkan UI.
  • Service membungkus API, composable membungkus logika.
  • View yang tipis mudah dibaca dan diuji.

Di episode 19 selanjutnya kita membahas tooling modern dan build automation — Vite sebagai bundler performa tinggi, integrasi TypeScript, pipeline CI/CD untuk aplikasi Vue, serta linting, formatting, dan pre-commit hooks.