Watch & watchEffect
Menjalankan efek samping saat data berubah: watch (sumber, immediate, deep), watchEffect, menghentikan watcher, dan kapan memilih computed vs watch.
Computed untuk nilai, watch untuk aksi
Computed menjawab "berapa nilainya?". Watch menjawab "apa yang harus dilakukan ketika data ini berubah?". Contoh kebutuhan watch: memanggil API saat kata kunci pencarian berubah, menyimpan ke localStorage, menampilkan notifikasi, atau mengatur ulang halaman ke 1 saat filter diganti.
watch(): memantau sumber tertentu
import { ref, watch } from 'vue'
const cari = ref('')
watch(cari, (baru, lama) => {
console.log(`Berubah dari "${lama}" ke "${baru}"`)
})
Argumen pertama adalah sumber. Callback menerima nilai baru dan lama.
| Sumber | Contoh |
|---|---|
| Satu ref | watch(cari, ...) |
| Getter | watch(() => profil.umur, ...) |
| Beberapa sumber (array) | watch([a, b], ([a1, b1]) => ...) |
Untuk memantau properti dari reactive, wajib memakai getter: watch(() => profil.umur, ...). Menulis watch(profil.umur, ...) memberi angka biasa, bukan sumber reaktif.
Opsi watch
| Opsi | Fungsi |
|---|---|
immediate: true | Jalankan callback langsung saat dibuat, tanpa menunggu perubahan |
deep: true | Pantau perubahan di dalam objek/array bersarang |
once: true | Hanya jalan sekali (Vue 3.4+) |
flush: 'post' | Jalankan setelah DOM diperbarui |
watch(
pengaturan,
(nilai) => localStorage.setItem('pengaturan', JSON.stringify(nilai)),
{ deep: true },
)
watchEffect(): otomatis melacak
watchEffect langsung dijalankan sekali, dan melacak sendiri semua data reaktif yang dipakai di dalamnya. Cocok bila kamu tidak peduli nilai lama dan malas menyebut sumber.
import { watchEffect } from 'vue'
const panjang = ref(0)
watchEffect(() => {
panjang.value = cari.value.length // otomatis berlangganan ke cari
})
| watch | watchEffect | |
|---|---|---|
| Sumber | Eksplisit | Otomatis (apa pun yang dibaca) |
| Jalan pertama kali | Tidak (kecuali immediate) | Ya, langsung |
| Nilai lama | Tersedia | Tidak |
Menghentikan watcher
Watcher yang dibuat saat komponen di-setup berhenti otomatis saat komponen dihancurkan. Untuk menghentikan manual:
const stop = watch(cari, () => { /* ... */ })
stop() // berhenti
Cleanup untuk efek asinkron
watch(id, async (baru, lama, onCleanup) => {
let batal = false
onCleanup(() => { batal = true }) // dipanggil sebelum callback berikutnya
const data = await ambil(baru)
if (!batal) hasil.value = data // abaikan respons usang
})
Computed atau watch?
Jika tujuannya menghasilkan nilai dari nilai lain → computed. Jika tujuannya efek samping (API, storage, log, timer) → watch. Sering kali pemula memakai watch untuk hal yang seharusnya computed.
Kesalahan umum
- Memakai
watchuntuk menyalin data ke variabel lain — itu pekerjaan computed. - Lupa getter saat memantau properti
reactive. - Watcher dibuat di dalam callback asinkron (
setTimeout) sehingga tidak otomatis berhenti → kebocoran memori.