Fortschritt
Ein Tracker sollte auf einen Blick zeigen, wie dein Tag läuft: 2 / 5 heute erledigt, einen Balken, der sich füllt, während du Gewohnheiten abhakst, und etwas Lob, sobald du alle erledigt hast.
All das entsteht aus gewohnheiten, ist also ein Fall für berechnete Werte, wie in der Lektion Berechnete Werte und Watcher. Vue berechnet sie neu, sobald sich eine Gewohnheit ändert, und die Seite ändert sich mit:
const anzahlErledigt = computed(() => {
return gewohnheiten.value.filter((gewohnheit) => gewohnheit.erledigt).length;
});
const prozent = computed(() => {
if (gewohnheiten.value.length === 0) {
return 0;
}
return Math.round((anzahlErledigt.value / gewohnheiten.value.length) * 100);
});
const alleErledigt = computed(() => {
return gewohnheiten.value.length > 0 && anzahlErledigt.value === gewohnheiten.value.length;
});
anzahlErledigt ist, wie viele Gewohnheiten erledigt sind, und prozent ist, wie viel das von allen in Prozent ist: 2 von 5 sind 40. Math.round() rundet auf eine ganze Zahl (1 von 3 wäre 33,333…). Ohne das if würde eine Liste ohne Gewohnheiten durch null teilen, und in JavaScript ist 0 / 0 gleich NaN, „not a number“. alleErledigt ist true, wenn jede Gewohnheit erledigt ist, aber nicht, wenn es gar keine Gewohnheiten gibt.
Der Balken besteht aus zwei Elementen: einem grauen Streifen mit der Klasse balken und einem grünen darin mit der Klasse fuellung, beide in style.css gestaltet. Der grüne ist so breit wie der Prozentwert. Die Breite ändert sich, also gehört sie in :style, wie in der Lektion Vorlagen-Syntax, und weil CSS eine Einheit braucht, bekommt die Zahl '%':
<div class="fortschritt">
<p>{{ anzahlErledigt }} / {{ gewohnheiten.length }} heute erledigt</p>
<div class="balken">
<div class="fuellung" :style="{ width: prozent + '%' }"></div>
</div>
<p v-if="alleErledigt">Alles für heute erledigt! 🎉</p>
</div>
Der Fortschritt gehört zur geladenen Seite, er soll also nur zusammen mit der Liste unter v-else erscheinen. Aber nur ein Element kann v-else haben, also verpacke beide in <template v-else>, wie in der Lektion Bedingungen und Listen: Es gruppiert sie, ohne ein Element zur Seite hinzuzufügen.
Typische Fehler:
anzahlErledigt / gewohnheiten.value.length, ohne.valuebeianzahlErledigt. Im Script ist ein berechneter Wert auch ein Ref, und das Ref selbst zu teilen ergibtNaN, sodass der Balken leer bleibt.width: prozent, ohne'%'. Der Browser ignoriert eine Breite ohne Einheit, und der Balken wächst nicht.
So schreibst du es:
Anweisungen
- 1
Füge
computedzum Import aus"vue"hinzu und schreibe die drei berechneten Werte von oben unter die Refs. Verpacke die Liste in der Vorlage in<template v-else>(dasulbraucht keinv-elsemehr) und setze dasdivmit der Klassefortschrittvon oben an den Anfang des<template v-else>, vorerst nur mit seinem ersten Absatz. Hake eine Gewohnheit ab:1 / 5 heute erledigt. - 2
Füge dem
divden Balken und das Lob hinzu, wie oben. Hake zwei Gewohnheiten ab, und der Balken füllt sich zu 40 %. Hake alle ab, und die Seite lobt dich.