Wat is een watcher?
Soms wil je iets doen als een waarde verandert — geen waarde berekenen, maar een actie uitvoeren. Bijvoorbeeld:
- Een waarde opslaan in
localStoragebij elke wijziging - De pagina-titel updaten als de gebruiker iets selecteert
- Een API call doen als een zoekterm verandert
Computed of watcher?
- Bereken je een waarde? → computed
- Doe je iets (side effect)? → watcher
watch() basics
Met watch() geef je een bron (een ref) en een callback die draait als die bron verandert.
import { watch } from 'vue'
Basis Syntax
watch(bron, (nieuweWaarde, oudeWaarde) => {
// Wat je wilt doen
})
Eerste voorbeeld
<script setup>
import { ref, watch } from 'vue'
const count = ref(0)
watch(count, (newVal, oldVal) => {
console.log(`count ging van ${oldVal} naar ${newVal}`)
})
</script>
<template>
<button @click="count++">Count: {{ count }}</button>
</template>
Voordeel van watch: je hebt toegang tot zowel de nieuwe als de oude waarde. Handig voor logging of het vergelijken van waardes.
Praktische Voorbeelden
1. Opslaan in localStorage
<script setup>
import { ref, watch } from 'vue'
const username = ref(localStorage.getItem('username') || '')
watch(username, (newName) => {
localStorage.setItem('username', newName)
})
</script>
<template>
<input v-model="username" />
</template>
2. Pagina-titel updaten
<script setup>
import { ref, watch } from 'vue'
const count = ref(0)
watch(count, (newCount) => {
document.title = `(${newCount}) Mijn App`
})
</script>
3. Form validatie
<script setup>
import { ref, watch } from 'vue'
const password = ref('')
const error = ref('')
watch(password, (newPwd) => {
if (newPwd.length < 8) {
error.value = 'Wachtwoord moet minimaal 8 tekens zijn'
} else {
error.value = ''
}
})
</script>
<template>
<input v-model="password" type="password" />
<p v-if="error">{{ error }}</p>
</template>
Belangrijke Regels
- Watcher = voor side effects (opslaan, API call, log) — niet voor afgeleide waardes
- Voor afgeleide waardes gebruik je
computed - Watchers zet je op top-level van
<script setup> - Standaard "lazy": draait pas bij wijziging — niet bij de eerste render
Veelgemaakte Fouten
Fout — .value meegeven i.p.v. de ref:
const count = ref(0)
watch(count.value, () => {...}) // ❌ je geeft een number, niet de ref
Goed:
watch(count, () => {...}) // ✅ de ref zelf
Fout — watcher gebruiken voor een afgeleide waarde:
const a = ref(1), b = ref(2)
const sum = ref(0)
watch([a, b], () => sum.value = a.value + b.value) // ❌ overkill
Goed — computed is hier perfect:
const sum = computed(() => a.value + b.value) // ✅