Komponen adalah satu potong tampilan yang berdiri sendiri: markup-nya, logikanya, dan gayanya. Halaman Warung Bu Sri disusun dari potongan-potongan seperti itu: papan nama di atas, daftar menu di tengah, info hak cipta di bawah. Bayangin rak etalase warung yang dibuat dari kotak-kotak terpisah. Tiap kotak dirakit sekali, bisa dipasang di mana saja, dan kalau kotak papan nama mau diganti, kotak lainnya gak ikut dibongkar. Di Vue, satu kotak itu satu komponen, dan biasanya tinggal di satu file berakhiran .vue.
🧪 Tebakan cepat: Template sebuah komponen berisi
<h1>Judul</h1>lalu<p>Paragraf</p>, tanpa elemen pembungkus. Di Vue 3, ini jalan atau error? Tebak dulu, jawabannya ada di bagian "Satu root atau banyak".
Anatomi file .vue
File .vue disebut Single File Component (SFC): satu file berisi tiga blok.
<!-- WarungFooter.vue -->
<script setup>
import { ref } from "vue"
const tahun = ref(2026)
</script>
<template>
<footer>
<p>© {{ tahun }}</p>
</footer>
</template>
<style scoped>
p {
color: #b45309;
font-weight: 700;
}
</style>
<script setup>berisi logika komponen. Variabel, fungsi, dan komponen yang di-import di sini langsung bisa dipakai di template. Di file.vue, barisimportwajib ditulis.<template>berisi markup-nya, dengan sintaks Vue seperti{{ tahun }}.<style scoped>berisi CSS yang cuma berlaku untuk elemen di komponen ini.- Nama file pakai PascalCase dan lebih dari satu kata, misalnya
WarungFooter.vue, supaya gak bentrok dengan tag HTML seperti<footer>.
File .vue dan editor latihan
Editor latihan BelajarWeb.dev menjalankan satu komponen, ditulis tanpa tag blok:
| Di file .vue | Di editor latihan |
|---|---|
isi <script setup>, tanpa baris import |
bagian di atas garis ---template--- |
isi <template> |
bagian di bawah garis ---template--- |
<style> |
gak ada tempatnya |
Kalau komponennya gak butuh data, editor langsung dibuka dengan garis ---template---. Begini satu halaman warung di editor:
---template---
<div>
<header><h1>Warung Bu Sri</h1></header>
<main><p>Menu hari ini: Nasi Goreng, Mie Ayam, Es Teh</p></main>
<footer><p>© 2026</p></footer>
</div>
<header>,<nav>,<main>, dan<footer>adalah elemen semantik. Tampilannya sama dengan<div>, tapi browser dan pembaca layar jadi tahu bagian mana kepala, navigasi, isi utama, dan kaki halaman.- Latihan memeriksa dengan selector CSS seperti
header h1, artinya<h1>yang ada di dalam<header>. Jadi<h1>harus ditaruh di dalam<header>, bukan di sebelahnya. - Jangan tempel file
.vueutuh ke editor. Tanpa garis---template---, semuanya dibaca sebagai template,<script>dibuang, dan isi<template>jatuh ke elemen yang gak terlihat. Halamannya kosong.
Menyusun komponen
Di proyek sungguhan, halaman dirakit dari komponen-komponen:
<!-- App.vue -->
<script setup>
import WarungHeader from "./WarungHeader.vue"
import WarungFooter from "./WarungFooter.vue"
</script>
<template>
<WarungHeader />
<main>
<p>Menu hari ini: Nasi Goreng, Mie Ayam, Es Teh</p>
</main>
<WarungFooter />
</template>
- Komponen yang di-import di
<script setup>langsung bisa dipakai sebagai tag:<WarungHeader />. Tag-nya boleh ditutup sendiri dengan/>. App.vuedisebut parent,WarungHeaderdanWarungFooterdisebut child.- Lupa baris
import-nya, Vue gak tahuWarungHeaderitu apa. Di mode development, console menulis[Vue warn]: Failed to resolve component: WarungHeader, dan yang muncul tag kosong<warungheader>. - Memasang
<WarungHeader />dua kali menghasilkan dua salinan. Cara mengirim data berbeda ke tiap salinan (props) ada di pelajaran berikutnya.
Satu root atau banyak
Root element adalah elemen paling luar di template. Template App.vue di atas punya tiga: <WarungHeader />, <main>, dan <WarungFooter />.
- Di Vue 3, banyak root boleh. Vue menyebutnya fragment. Jadi template dengan
<h1>dan<p>tanpa pembungkus jalan normal. Itu jawaban tebakannya. - Di Vue 2, template wajib punya tepat satu root. Template tadi ditolak dengan error
Component template should contain exactly one root element. If you are using v-if on multiple elements, use v-else-if to chain them instead.Obatnya: bungkus semuanya dengan satu<div>. - Pembungkus
<div>masih sering dipakai di Vue 3 karena rapi, dan starter latihan juga memakainya.
Gaya yang gak bocor: scoped
Tanpa scoped, aturan p { color: #b45309 } di WarungFooter.vue berlaku untuk semua <p> di halaman, termasuk paragraf menu milik App.vue. Dengan scoped, Vue menempelkan atribut unik ke tiap elemen komponen itu dan menulis ulang selector-nya:
<footer data-v-1f42fb90><p data-v-1f42fb90>© 2026</p></footer>
<style>
p[data-v-1f42fb90] { color: #b45309; font-weight: 700; }
</style>
Selector p[data-v-1f42fb90] cuma cocok dengan <p> milik WarungFooter, jadi paragraf menu gak ikut berwarna.
⚠️ Jebakan yang sering ketemu
- Menempel file .vue utuh ke editor latihan. Halamannya kosong. Di editor, tulis isi script, garis
---template---, lalu isi template. - Elemen di tempat yang salah. Latihan mencari
header h1,footer p, danmain p.<h1>di luar<header>gak terhitung, walau tampilannya mirip. - Teks gak persis.
© 2026harus pakai simbol ©, spasi, lalu tahunnya. Simbolnya boleh diketik langsung atau ditulis©. <style>tanpascoped. Aturannya bocor ke seluruh halaman dan mewarnai elemen komponen lain.
TL;DR: Komponen adalah satu potong tampilan dengan markup, logika, dan gayanya sendiri. Di proyek sungguhan dia tinggal di file .vue (Single File Component) berisi <script setup>, <template>, dan <style scoped>. Komponen yang di-import bisa dipakai sebagai tag, misalnya <WarungHeader />. Di editor latihan, satu komponen ditulis sebagai isi script, garis ---template---, lalu isi template, tanpa import dan tanpa <style>. Vue 3 boleh punya banyak root element, Vue 2 wajib satu. scoped membuat CSS cuma berlaku untuk komponennya sendiri.