Modul 2: Vue Grundlagen

Bedingte Darstellung

Elemente dynamisch ein- und ausblenden mit v-if, v-else und v-show

Einführung

In fast jeder Anwendung musst du Inhalte bedingt anzeigen: Fehlermeldungen, Ladezustände, verschiedene Ansichten je nach Benutzerrolle. Vue bietet dafür zwei Ansätze: v-if (Element wird aus dem DOM entfernt) und v-show (Element wird per CSS versteckt).

🛤️

Rails-Vergleich: ERB Conditionals

In Rails-Views verwendest du Ruby-Conditionals innerhalb von ERB-Tags. Das Ergebnis wird einmalig auf dem Server berechnet. In Vue sind Bedingungen reaktiv — änderst du den Wert, aktualisiert sich die Anzeige sofort.

Rails ERB Conditional
<!-- Rails: Server-seitig, einmalig -->
<% if @user.admin? %>
  <div class='admin-panel'>Admin-Bereich</div>
<% elsif @user.moderator? %>
  <div class='mod-panel'>Moderator-Bereich</div>
<% else %>
  <div class='user-panel'>Benutzer-Bereich</div>
<% end %>

<!-- Oft auch mit Hilfsmethoden -->
<%= render 'admin_panel' if @user.admin? %>
Vue Conditional
<!-- Vue: Client-seitig, reaktiv -->
<div v-if="user.role === 'admin'" class='admin-panel'>
  Admin-Bereich
</div>
<div v-else-if="user.role === 'moderator'" class='mod-panel'>
  Moderator-Bereich
</div>
<div v-else class='user-panel'>
  Benutzer-Bereich
</div>

v-if — Bedingt rendern

v-if rendert ein Element nur, wenn die Bedingung truthy ist. Ist die Bedingung falsy, wird das Element komplett aus dem DOM entfernt.

VIfBeispiel.vue
<script setup>
import { ref } from 'vue'

const istAngemeldet = ref(false)
const hatNachrichten = ref(true)
const nachrichtenAnzahl = ref(5)
</script>

<template>
  <!-- Einfaches v-if -->
  <p v-if="istAngemeldet">Willkommen zurück!</p>

  <!-- v-if mit Vergleich -->
  <span v-if="nachrichtenAnzahl > 0" class="badge">
    {{ nachrichtenAnzahl }} neue Nachrichten
  </span>

  <!-- v-if mit logischen Operatoren -->
  <div v-if="istAngemeldet && hatNachrichten">
    Du hast ungelesene Nachrichten!
  </div>
</template>

v-else-if und v-else

Wie in jeder Programmiersprache kannst du v-else-if und v-else für Verzweigungen verwenden. Wichtig: Sie müssen direkt nach einem v-if bzw. v-else-if-Element stehen — ohne Elemente dazwischen.

VElseBeispiel.vue
<script setup>
import { ref } from 'vue'

const status = ref('laden')  // 'laden' | 'erfolg' | 'fehler' | 'leer'
const punktzahl = ref(75)
</script>

<template>
  <!-- Ladezustand-Muster (sehr häufig!) -->
  <div v-if="status === 'laden'">
    ⏳ Daten werden geladen...
  </div>
  <div v-else-if="status === 'fehler'">
    ❌ Ein Fehler ist aufgetreten.
  </div>
  <div v-else-if="status === 'leer'">
    📭 Keine Daten vorhanden.
  </div>
  <div v-else>
    ✅ Daten erfolgreich geladen!
  </div>

  <!-- Bewertung -->
  <p v-if="punktzahl >= 90">🏆 Sehr gut!</p>
  <p v-else-if="punktzahl >= 70">👍 Gut</p>
  <p v-else-if="punktzahl >= 50">📝 Ausreichend</p>
  <p v-else>❌ Nicht bestanden</p>
</template>
⚠️

Häufiger Fehler: Element dazwischen

v-else und v-else-if müssen direkt auf ein v-if-Element folgen. Ein Element dazwischen bricht die Kette:

FehlerBeispiel.vue
<!-- ❌ FALSCH: <p> unterbricht die Kette -->
<div v-if="a">A</div>
<p>Irgendein Text</p>
<div v-else>B</div>  <!-- Vue-Fehler! -->

<!-- ✅ RICHTIG: Direkt aufeinander -->
<div v-if="a">A</div>
<div v-else>B</div>

template v-if — Gruppen bedingt rendern

Was, wenn du mehrere Elemente gleichzeitig bedingt anzeigen willst, aber kein Wrapper-Element im DOM haben möchtest? Verwende <template> als unsichtbaren Container:

TemplateVIf.vue
<template>
  <!-- template wird NICHT im DOM gerendert -->
  <template v-if="istAngemeldet">
    <h2>Dashboard</h2>
    <nav>Navigation für angemeldete Benutzer</nav>
    <main>Dein persönlicher Bereich</main>
  </template>

  <template v-else>
    <h2>Willkommen</h2>
    <p>Bitte melde dich an, um fortzufahren.</p>
    <button>Anmelden</button>
  </template>
</template>
💡

Warum template statt div?

Ein <div> als Wrapper würde ein zusätzliches Element im DOM erzeugen, das Layout und CSS beeinflussen kann. <template> ist ein „unsichtbarer" Container — Vue rendert nur den Inhalt, nicht das Template-Tag selbst.

v-show — Per CSS ein-/ausblenden

v-show schaltet nur die CSS-Eigenschaft display um. Das Element bleibt immer im DOM — es wird nur visuell versteckt.

VShowBeispiel.vue
<script setup>
import { ref } from 'vue'

const istSichtbar = ref(true)
</script>

<template>
  <button @click="istSichtbar = !istSichtbar">Toggle</button>

  <!-- v-show: Immer im DOM, nur display: none -->
  <div v-show="istSichtbar">
    Ich bin sichtbar!
  </div>

  <!-- Im DOM wenn istSichtbar === false: -->
  <!-- <div style="display: none;">Ich bin sichtbar!</div> -->
</template>

v-if vs v-show — Wann was verwenden?

Vergleich.vue
<!-- v-if: Element wird komplett entfernt/eingefügt -->
<!-- ✅ Gut für: Selten wechselnde Bedingungen -->
<!-- ✅ Gut für: Große Bereiche mit vielen Kind-Elementen -->
<!-- ✅ Unterstützt: v-else-if, v-else -->
<!-- ❌ Teurer bei häufigem Wechsel -->
<div v-if="istAdmin">Admin-Panel</div>

<!-- v-show: Element bleibt im DOM, nur CSS toggle -->
<!-- ✅ Gut für: Häufiges Umschalten (Tabs, Tooltips) -->
<!-- ✅ Schneller Toggle-Wechsel -->
<!-- ❌ Element ist IMMER im DOM (auch wenn versteckt) -->
<!-- ❌ Kein v-else, kein template v-show -->
<div v-show="istSichtbar">Tooltip-Inhalt</div>
ℹ️

Faustregel

v-if = Höhere Kosten beim Umschalten, niedrigere Kosten wenn nicht gerendert. Wähle v-if, wenn sich die Bedingung selten ändert.

v-show = Niedrige Kosten beim Umschalten, Element ist immer im DOM. Wähle v-show, wenn du häufig umschaltest (z.B. Tabs, Dropdown-Menüs).

Einschränkungen von v-show

VShowEinschraenkungen.vue
<!-- ❌ v-show funktioniert NICHT auf <template> -->
<template v-show="ok">  <!-- Fehler! -->
  <p>Das geht nicht</p>
</template>

<!-- ❌ v-show hat KEIN v-else -->
<div v-show="ok">Ja</div>
<div v-show="!ok">Nein</div>  <!-- So musst du es machen -->

<!-- ✅ v-if unterstützt beides -->
<template v-if="ok">
  <p>Ja</p>
</template>
<template v-else>
  <p>Nein</p>
</template>

Interaktive Demo

Probiere v-if und v-show selbst aus und beobachte die Unterschiede:

Bedingte Darstellung Live-Demo
Interaktiv

v-if / v-else-if / v-else — Statusanzeige

Lädt... Daten werden vom Server geholt.

v-if vs v-show — Vergleich

v-if="true"

🟦 Ich existiere im DOM!

v-show="true"

🟪 Ich bin immer im DOM!

Bewertungs-Rechner mit v-if

050100
👍 Gut (75%)

Benutzerdetails ein-/ausblenden

Zusammenfassung

💡

Das Wichtigste auf einen Blick

  • v-if — Element wird komplett aus dem DOM entfernt/eingefügt
  • v-else-if / v-else — Verzweigungen (müssen direkt aufeinander folgen)
  • v-show — Nur CSS display: none Toggle
  • <template v-if> — Gruppen bedingt rendern ohne Wrapper
  • Faustregel: v-if für seltene Wechsel, v-show für häufige
  • v-show hat kein v-else und funktioniert nicht auf <template>