Styling Komponen — Vue

Scoped Styles Di SFC, tambahkan scoped agar style hanya berlaku untuk komponen itu: .card { border: 1px solid #ddd; padding: 16px; } Dynamic Class Binding…

Di Vue, data bisa menentukan class dan gaya inline sebuah elemen lewat :class dan :style, dan <style scoped> menjaga CSS sebuah komponen supaya gak bocor ke komponen lain. Bayangin papan menu Warung Bu Sri. Waktu pembeli memilih sebuah menu, Bu Sri menjepitkan penanda kuning di kartunya. Waktu menu habis, kartunya dicoret abu-abu. Penanda itu datang dan pergi mengikuti keadaan, persis class yang dipasang :class. Dan cat papan Bu Sri diberi label "khusus Warung Bu Sri", supaya tukang cat gak ikut mengecat papan warung sebelah dengan warna yang sama: itu scoped.

🧪 Tebakan cepat: pilihan berisi "Mie Ayam", dan stok Mie Ayam 0. Baris menunya ditulis <li class="item" :class="{ dipilih: m.nama === pilihan, habis: m.stok === 0 }">. Atribut class apa yang dipasang di baris Mie Ayam? Tebak dulu, jawabannya ada di bagian ":class dengan object".

:class dengan object

const pilihan = ref("Mie Ayam")
const menu = ref([
  { id: 1, nama: "Nasi Goreng", stok: 5 },
  { id: 2, nama: "Mie Ayam", stok: 0 },
  { id: 3, nama: "Es Teh", stok: 10 },
])

---template---
<ul>
  <li
    v-for="m in menu"
    :key="m.id"
    class="item"
    :class="{ dipilih: m.nama === pilihan, habis: m.stok === 0 }"
    @click="pilihan = m.nama"
  >
    {{ m.nama }}
  </li>
</ul>

Hasil render-nya:

<ul>
  <li class="item">Nasi Goreng</li>
  <li class="item dipilih habis">Mie Ayam</li>
  <li class="item">Es Teh</li>
</ul>

Baris Mie Ayam mendapat class="item dipilih habis". Itu jawaban tebakannya.

:class dengan array

const ukuran = ref("besar")
const dipilih = ref(true)

---template---
<p :class="['kartu', ukuran, { dipilih: dipilih }]">Nasi Goreng</p>

Hasilnya <p class="kartu besar dipilih">.

:style: gaya inline dari data

const warna = ref("#b45309")
const besar = ref(18)

---template---
<p :style="{ color: warna, fontSize: besar + 'px', 'font-weight': 700 }">Promo hari ini</p>

Hasilnya <p style="color: rgb(180, 83, 9); font-size: 18px; font-weight: 700;">.

Scoped styles di file .vue

<!-- MenuList.vue -->
<script setup>
import { ref } from "vue"

const pilihan = ref("Mie Ayam")
</script>

<template>
  <h3 class="judul">Menu</h3>
  <p class="item" :class="{ dipilih: pilihan === 'Mie Ayam' }">Mie Ayam</p>
</template>

<style scoped>
.judul { color: #b45309; }
.dipilih { background: #fef3c7; }
</style>

Yang dihasilkan build-nya, kira-kira:

<h3 data-v-7a3f2c1e="" class="judul">Menu</h3>
<p data-v-7a3f2c1e="" class="item dipilih">Mie Ayam</p>
.judul[data-v-7a3f2c1e] { color: #b45309; }
.dipilih[data-v-7a3f2c1e] { background: #fef3c7; }

⚠️ Jebakan yang sering ketemu

TL;DR: :class="{ dipilih: m.nama === pilihan }" memasang class saat syaratnya benar dan melepasnya saat salah; array seperti ['kartu', ukuran, { dipilih }] menggabungkan beberapa class, dan class biasa ikut digabung. :style="{ color: color, padding: '20px' }" memasang gaya inline dari data, nama propertinya camelCase, dan Vue gak menambahkan px, jadi angka butuh satuannya. <style scoped> di file .vue memberi elemen komponen atribut data-v-... dan menulis ulang selector-nya, jadi CSS komponen itu gak bocor ke komponen lain.

Yang akan kamu pelajari