Technical Comparison: Global Event Bus vs. Local Component Events (Vue 2)
1. Summary Comparison Table
| Kriteria | Global Event Bus (this.$root.$emit / Custom Bus) | Local Component Event (this.$emit) |
|---|---|---|
| Ruang Lingkup (Scope) | Global / Seluruh Aplikasi. Komponen mana pun bisa mengirim dan mendengarkan event tanpa peduli hubungannya. | Lokal (Parent-Child). Hanya berlaku dari komponen anak langsung ke komponen induknya. |
| Pembersihan Memori (GC) | Manual. Harus dilepas secara manual menggunakan $off di hook beforeDestroy() agar tidak bocor (memory leak). | Otomatis. Vue secara otomatis menghapus dan membersihkan listener lokal ketika komponen dihancurkan. |
| Keterbacaan Kode | Implisit / Tersembunyi. Hubungan pengirim dan penerima tidak terlihat di file template HTML. | Eksplisit / Terang. Hubungan pengirim dan penerima terlihat jelas di tag template HTML (@event-name="..."). |
| Risiko Konflik Nama | Tinggi. Risiko tabrakan nama event besar jika tidak diberi prefix unik (misal: tabrakan nama event 'loading'). | Sangat Rendah. Nama event terisolasi hanya pada hubungan komponen tersebut. |
2. Cara Kerja Global Event Bus
Global Event Bus menggunakan satu instance Vue terpusat (baik objek $root bawaan Vue atau berkas khusus event-bus.js) untuk memancarkan event ke seluruh penjuru aplikasi.
Hubungan Komponen:
Bisa digunakan untuk komunikasi antar komponen yang tidak berhubungan keluarga langsung (misal: Sibling, Grandchild ke Grandparent, atau Sidebar ke Toolbar).
[ Root App ]
/ \
[Sidebar] [ChatArea]
| |
[UserCard] [InputBar] <-- Ingin kirim data dari UserCard ke InputBar
Implementasi:
// Di Komponen A (Pengirim)
this.$root.$emit('fitur-ai:draf-siap', data);
// Di Komponen B (Penerima)
created() {
this.$root.$on('fitur-ai:draf-siap', this.handleEvent);
},
beforeDestroy() {
// WAJIB: Agar tidak terjadi memory leak (pemanggilan ganda di masa depan)
this.$root.$off('fitur-ai:draf-siap', this.handleEvent);
}
3. Cara Kerja Local Component Event ($emit Bawaan)
Local Event adalah cara komunikasi bawaan Vue yang dikirimkan ke atas (bubble up) khusus untuk induk langsungnya (Direct Parent).
Hubungan Komponen:
Hanya berlaku dari Anak langsung ke Induknya.
[ChatArea] (Induk)
|
[AskAiShortcut] (Anak) <-- Ingin mengirim data ke ChatArea
Implementasi:
// Di Komponen Anak (Pengirim)
this.$emit('draft-ready', text);
<!-- Di Komponen Induk (Penerima - Terbaca Jelas di HTML) -->
<AskAiShortcut @draft-ready="handleDraftReady" />
4. Rekomendasi Penggunaan
- Gunakan Local Event (
$emitlokal) jika Anda sedang berkomunikasi dari komponen anak langsung ke induknya (seperti tombolAskAiShortcutkeBchatArea). Ini jauh lebih bersih, aman dari kebocoran memori, dan mudah dipahami jalurnya di file HTML. - Gunakan Global Event Bus hanya jika Anda perlu mengirim data lintas komponen yang tidak memiliki hubungan keluarga dekat (misalnya: ketika sebuah event di sidebar profil pelanggan harus memicu sesuatu di dalam kotak input chat).