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 localStorage bij 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)        // ✅