Einen Timer stoppen
Manches, das eine Komponente startet, läuft von allein weiter. Ein Intervall von setInterval() läuft immer wieder, bis es jemand mit clearInterval() stoppt, wie du aus dem JavaScript-Kurs weißt. Wenn eine Komponente eines startet, muss sie es auch stoppen, wenn sie ausgehängt wird. Hier ist ein Banner, das alle drei Sekunden ein anderes Angebot des Cafés zeigt:
<script setup>
import { onMounted, onUnmounted, ref } from "vue";
const angebote = ["Karottenkuchen", "Käsekuchen", "Pfefferminztee"];
const position = ref(0);
let timer;
onMounted(() => {
timer = setInterval(() => {
position.value = (position.value + 1) % angebote.length;
}, 3000);
});
onUnmounted(() => {
clearInterval(timer);
});
</script>
<template>
<p>Probiere unseren {{ angebote[position] }}!</p>
</template>%, der Rest, bringt position nach dem letzten Angebot wieder auf 0. Und beachte:
timerist mitletaußerhalb beider Hooks deklariert, damit beide es benutzen können:onMountedspeichert die ID des Intervalls darin, undonUnmountedstoppt dieses Intervall.- Das Intervall startet in
onMounted. Oben im<script setup>würde es auch funktionieren, aber inonMountedstartet es, wenn die Komponente auf der Seite ist, und die beiden Hooks lesen sich als Paar: Was einer startet, stoppt der andere.
Was, wenn onUnmounted fehlt? Ein Intervall weiß nichts von Komponenten. Wenn Vue das Banner aus der Seite entfernt, läuft das Intervall weiter, solange die Seite offen ist, und ändert einen Ref, den nichts mehr zeigt. Jedes Mal, wenn das Banner wieder erscheint, startet eine neue Komponente ein weiteres Intervall. Auf der Seite siehst du das nicht, aber in der Konsole, und genau das machst du in dieser Übung.
Dasselbe gilt für ein setTimeout(), das noch nicht gelaufen ist, oder einen Listener, der mit window.addEventListener() hinzugefügt wurde: Was eine Komponente startet, stoppt onUnmounted.
Ein typischer Fehler: const timer = setInterval(…) innerhalb von onMounted. Diese Konstante gibt es nur in der Funktion von onMounted, also kann onUnmounted das Intervall nicht stoppen.
So schreibst du es:
Anweisungen
- 1
Starte in
Timer.vueinonMountedein Intervall: Alle 1000 Millisekunden erhöht essekundenum 1 und gibt die Zeit mitconsole.log(`Wartezeit: ${sekunden.value} s`);in der Konsole aus. - 2
Klicke auf
Timer ausblendenund sieh in die Konsole: Der Timer ist weg, aber die Zeilen kommen weiter. Klicke aufTimer zeigen: Jetzt wechseln sich die Zeiten von zwei Intervallen in der Konsole ab. Behebe das: Deklarierelet timer;überonMounted, speichere die ID des Intervalls darin und stoppe das Intervall inonUnmountedmitclearInterval(timer).