Komponen: Memecah UI Jadi Bagian Kecil
Membuat komponen .vue, mengimpor dan memakainya, state yang terpisah di tiap instance, aturan penamaan, scoped style, dan fallthrough atribut.
Mengapa komponen?
Aplikasi nyata punya puluhan bagian yang berulang: tombol, kartu produk, baris tabel, modal. Menyalin-tempel HTML-nya ke mana-mana membuat perubahan kecil harus diulang di banyak tempat. Komponen memungkinkan kamu menulis sekali lalu memakainya berkali-kali — seperti membuat "tag HTML buatan sendiri".
Prinsip desain yang baik: satu komponen = satu tanggung jawab. Jika sebuah file terasa terlalu panjang atau kamu menyalin potongan yang sama, itu tanda untuk memecahnya.
Membuat dan memakai komponen
1. Tulis komponen (src/components/Tombol.vue):
<template>
<button class="tombol" @click="jumlah++">Klik: {{ jumlah }}</button>
</template>
<script setup>
import { ref } from 'vue'
const jumlah = ref(0)
</script>
<style scoped>
.tombol { padding: 6px 14px; }
</style>
2. Impor lalu pakai di komponen lain:
<script setup>
import Tombol from './Tombol.vue'
</script>
<template>
<Tombol />
<Tombol />
</template>
Dengan <script setup>, komponen yang diimpor otomatis tersedia di template — tidak perlu didaftarkan lagi.
Setiap instance punya state sendiri
Dua <Tombol /> di atas masing-masing memiliki jumlah sendiri. Mengklik yang pertama tidak mengubah yang kedua. Inilah yang membuat komponen bisa dipakai ulang dengan aman.
Aturan penamaan
| Hal | Konvensi |
|---|---|
| Nama file | PascalCase: KartuProduk.vue |
| Dipakai di template | <KartuProduk /> (atau <kartu-produk />) |
| Tag kosong | Gunakan self-closing: <Tombol /> |
| Nama minimal | Dua kata untuk komponen umum agar tak bentrok dengan elemen HTML (TombolUtama, bukan Tombol) — di latihan kita bebas |
Penanda berkas di editor latihan
Karena editor kita satu kotak, beberapa file dipisah dengan baris komentar khusus. Bagian pertama selalu App.vue; setiap penanda memulai berkas baru:
(isi App.vue)
<!-- file: Tombol.vue -->
(isi Tombol.vue)
Impor seperti biasa: import Tombol from './Tombol.vue'. Di proyek sungguhan, penanda ini tidak ada — masing-masing adalah file sendiri.
Scoped style
<style scoped> menambahkan atribut unik pada elemen komponen sehingga CSS-nya tidak bocor ke komponen lain. Tanpa scoped, CSS berlaku global.
Fallthrough atribut
Atribut yang kamu berikan pada komponen tetapi tidak dideklarasikan sebagai prop akan "jatuh" ke elemen akarnya.
<Tombol class="besar" id="utama" />
Hasilnya, <button class="tombol besar" id="utama">. Ini berguna untuk menambah class dari luar.
Struktur folder yang rapi
src/
├─ components/ komponen yang dipakai ulang (Tombol, Kartu, Modal)
├─ views/ halaman utuh (dipakai bersama Vue Router)
└─ composables/ logika reaktif yang dipakai ulang (bab 18)
Kesalahan umum
- Lupa mengimpor komponen → peringatan "Failed to resolve component" dan elemen tampil sebagai tag kosong.
- Memakai nama yang sama dengan elemen HTML bawaan.
- Mengira data dibagi antar instance. Untuk berbagi data, gunakan props (bab 12), provide/inject (bab 19), atau Pinia (bab 22).