Setiap komponen punya siklus hidup: dibuat, dipasang ke halaman, diperbarui saat datanya berubah, lalu dilepas dari halaman. Lifecycle hook adalah fungsi yang kamu titipkan ke Vue supaya dijalankan di salah satu momen itu. Bayangin satu hari di Warung Bu Sri. Pagi, bahan disiapkan di dapur (setup). Rolling door dibuka dan warungnya kelihatan dari jalan (mounted): baru sekarang papan menu bisa ditulis jam bukanya. Sepanjang hari papan diperbarui setiap ada menu habis (updated). Malam, sebelum pulang, kompor dimatikan (unmounted). Hook itu daftar tugas yang ditempel di tiap momen.
🧪 Tebakan cepat:
Appdan duaMenuCarddi dalamnya sama-sama menulis ke console dionMounted. Mana yang muncul duluan:App: onMountedatauonMountedmilikMenuCard? Tebak dulu, jawabannya ada di bagian "Urutan hook, parent dan child".
onMounted: komponen sudah ada di halaman
Kode ini bisa langsung dijalankan di editor latihan:
console.log("setup jalan")
console.log("h1 di setup:", document.querySelector("h1"))
onMounted(() => {
console.log("Komponen dimuat!")
console.log("h1 di onMounted:", document.querySelector("h1").textContent)
})
---template---
<h1>Warung Bu Sri</h1>
Console:
setup jalan
h1 di setup: null
Komponen dimuat!
h1 di onMounted: Warung Bu Sri
- Script komponen jalan duluan, di tahap setup. Saat itu elemennya belum ada di halaman, jadi
document.querySelector("h1")menghasilkannull. onMounted(() => { ... })menitipkan fungsi yang dijalankan setelah komponen dan semua child-nya terpasang di DOM. Di sana elemennya sudah bisa dibaca.- Di file
.vue, hook di-import dulu:import { onMounted } from "vue". Editor latihan sudah menyediakannya, jadi di sana barisimportboleh ditulis, boleh juga gak.
Mengisi data begitu komponen tampil
const waktu = ref("")
onMounted(() => {
waktu.value = "Dimuat pada: " + new Date().toLocaleTimeString()
})
---template---
<p id="waktu">{{ waktu }}</p>
| Saat | Isi <p id="waktu"> |
|---|---|
| render pertama | kosong |
onMounted jalan |
Dimuat pada: 10.15.30 |
<p>-nya sudah ada sejak render pertama, isinya menyusul begituonMountedmengisi refwaktu.- Format jamnya ikut bahasa browser:
10.15.30untuk bahasa Indonesia,10:15:30 AMuntuk bahasa Inggris AS. - Pola yang sama dipakai untuk mengambil data menu dari server begitu komponen tampil. Caranya dibahas di pelajaran fetching data.
Urutan hook, parent dan child
Di editor, onBeforeMount, onMounted, onBeforeUnmount, dan onUnmounted sudah tersedia. Child yang ditulis sebagai objek memanggil hook-nya di dalam setup(props):
console.log("App: setup")
onBeforeMount(() => console.log("App: onBeforeMount"))
onMounted(() => console.log("App: onMounted"))
const MenuCard = {
props: ["nama"],
setup(props) {
console.log(props.nama + ": setup")
onBeforeMount(() => console.log(props.nama + ": onBeforeMount"))
onMounted(() => console.log(props.nama + ": onMounted"))
},
template: `<li>{{ nama }}</li>`,
}
---template---
<ul>
<component :is="MenuCard" nama="Nasi Goreng" />
<component :is="MenuCard" nama="Es Teh" />
</ul>
Console:
App: setup
App: onBeforeMount
Nasi Goreng: setup
Nasi Goreng: onBeforeMount
Es Teh: setup
Es Teh: onBeforeMount
Nasi Goreng: onMounted
Es Teh: onMounted
App: onMounted
Parent mulai duluan, tapi selesai paling akhir: kedua MenuCard terpasang dulu, baru App: onMounted. App baru dianggap terpasang kalau semua child-nya sudah ada. Itu jawaban tebakannya.
| Kejadian | Hook yang jalan, berurutan |
|---|---|
| data App berubah, template-nya render ulang | onBeforeUpdate, lalu onUpdated |
v-if membuang daftar menu |
App onBeforeUpdate, tiap MenuCard onBeforeUnmount, lalu tiap onUnmounted, terakhir App onUpdated |
v-show menyembunyikan daftar menu |
cuma App onBeforeUpdate dan onUpdated; MenuCard tetap terpasang |
onUnmounted: bersih-bersih
onUnmounted jalan saat komponen dilepas dari DOM, misalnya karena v-if jadi false atau pindah halaman. Di sinilah timer, event listener, dan langganan data dibereskan:
const detik = ref(0)
let timer
onMounted(() => {
timer = setInterval(() => detik.value++, 1000)
})
onUnmounted(() => {
clearInterval(timer)
})
Tanpa clearInterval, timernya tetap jalan setiap detik walau komponennya sudah hilang.
📌 onUpdated di editor latihan
Editor gak menyediakan onBeforeUpdate dan onUpdated secara langsung; memanggilnya menghasilkan error onUpdated is not defined. Ambil dari objek Vue di baris pertama script: const { onBeforeUpdate, onUpdated } = Vue. Di file .vue, keduanya di-import dari "vue" seperti hook lain.
⚠️ Jebakan yang sering ketemu
- Lupa meng-import hook di proyek sungguhan. Editor latihan menyediakan
onMounted, tapi di file.vuesungguhan tanpaimport { onMounted } from "vue"halamannya berhenti denganReferenceError: onMounted is not defined. - Menyentuh DOM di setup. Elemennya belum ada, hasilnya
null. Pindahkan keonMounted. - Mendaftarkan hook terlambat.
onMounteddi dalamsetTimeoutatau sesudahawaitgak pernah jalan. Build development menulis[Vue warn]: onMounted is called when there is no active component instance to be associated with.Panggil hook langsung di setup. - Lupa membereskan timer. Pasang di
onMounted, hentikan dionUnmounted. - Teks gak persis. Latihan mencari
Komponen dimuat!di console dan awalanDimuat pada:di<p id="waktu">.
TL;DR: Lifecycle hook menjalankan kode di momen tertentu hidup komponen: setup, onBeforeMount, onMounted, onBeforeUpdate, onUpdated, onBeforeUnmount, onUnmounted. onMounted jalan setelah komponen dan semua child-nya ada di DOM, jadi itu tempat membaca elemen, mengisi data awal, atau memasang timer; child selesai terpasang sebelum parent-nya. onUnmounted jalan saat komponen dilepas, misalnya oleh v-if, tapi gak oleh v-show, dan di sanalah timer dihentikan. Di file .vue hook di-import dari "vue"; di editor latihan onMounted dan kawan-kawannya langsung tersedia.