Emits: Komunikasi dari Anak ke Induk

defineEmits, mengirim event dengan payload, mendengarkan event kustom di induk, validasi emit, dan pola "props turun, event naik".

Part 13 dari 25 ± 45 menit Gratis

Props turun, event naik

Props hanya membawa data dari induk ke anak. Bagaimana kalau anak ingin memberi tahu induk bahwa "tombol ini diklik" atau "item ini dihapus"? Caranya: anak memancarkan (emit) event kustom, dan induk mendengarkannya dengan @ — persis seperti event DOM.

Pola ini disebut props down, events up dan menjaga aliran data tetap mudah dilacak.

Mendeklarasikan dan memancarkan event

<!-- Anak: Penghitung.vue -->
<script setup>
const emit = defineEmits(['tambah', 'reset'])
</script>

<template>
  <button @click="emit('tambah', 1)">+1</button>
  <button @click="emit('reset')">Reset</button>
</template>
<!-- Induk -->
<Penghitung @tambah="total += $event" @reset="total = 0" />
<Penghitung @tambah="tambah" />      <!-- method menerima payload -->

function tambah(n) { total.value += n }
  • emit('nama', ...argumen) — argumen tambahan menjadi payload yang diterima handler.
  • Di induk, payload pertama tersedia sebagai $event di inline handler, atau sebagai argumen di method handler.
  • Gunakan nama kebab-case bila event bernama majemuk: emit('selesai-diubah') → @selesai-diubah (camelCase di emit juga didukung).

Emit di template tanpa variabel

Di template tersedia $emit langsung, tanpa perlu menyimpan hasil defineEmits:

<button @click="$emit('tambah', 1)">+1</button>

Untuk memancarkan dari script, simpan dulu: const emit = defineEmits([...]).

Validasi event (bentuk objek)

const emit = defineEmits({
  tambah: (n) => typeof n === 'number',     // validator: true = valid
  reset: null,                              // tanpa validasi
})

Contoh nyata: item daftar yang bisa dihapus

<!-- ItemTugas.vue -->
<script setup>
defineProps({ tugas: Object })
const emit = defineEmits(['hapus'])
</script>
<template>
  <li>{{ tugas.judul }} <button @click="emit('hapus', tugas.id)">x</button></li>
</template>

<!-- Induk -->
<ItemTugas v-for="t in daftar" :key="t.id" :tugas="t" @hapus="hapusTugas" />

function hapusTugas(id) { daftar.value = daftar.value.filter(t => t.id !== id) }

Perhatikan: anak tidak menghapus data sendiri (ia tak memilikinya). Anak hanya melapor, induk yang memutuskan dan mengubah datanya.

Props vs emits dalam sekali pandang

PropsEmits
ArahInduk → AnakAnak → Induk
DeklarasidefinePropsdefineEmits
Pemakaian induk:nama="x"@nama="handler"

Kesalahan umum

  • Memakai event native tanpa mendeklarasikannya: event yang tak dideklarasikan di defineEmits diperlakukan sebagai listener native yang jatuh ke elemen akar.
  • Mengubah props di anak sebagai "cara cepat" ketimbang emit.
  • Lupa bahwa emit tidak naik bertingkat seperti event DOM: hanya induk langsung yang mendengar. Untuk jarak jauh pakai provide/inject atau Pinia.

Praktikkan langsung, gratis

Tulis dan jalankan kode langsung di browser, dapatkan penilaian otomatis. Daftar gratis kapan saja untuk menyimpan progres dan meraih sertifikat.

Coba latihan sekarang, tanpa daftar
Bagikan: WhatsApp Facebook LinkedIn X