Template-Syntax
Wie Vue.js Templates funktionieren — von Interpolation bis dynamischen Attributen
Einführung
Vue.js verwendet eine HTML-basierte Template-Syntax, die es dir ermöglicht, das gerenderte DOM deklarativ an die Daten deiner Komponente zu binden. Wenn du aus der Rails-Welt kommst, wirst du viele Parallelen zu ERB-Templates finden — aber mit einem entscheidenden Unterschied: Vue-Templates sind reaktiv. Änderungen an den Daten aktualisieren automatisch das DOM.
Rails-Vergleich: ERB vs Vue Templates
In Rails schreibst du <%= @user.name %> in ERB-Templates. Vue verwendet stattdessen doppelte geschweifte Klammern: {{ user.name }}. Der große Unterschied: ERB wird einmalig auf dem Server gerendert, Vue-Templates werden reaktiv im Browser aktualisiert.
<!-- Rails: Einmaliges Server-Rendering -->
<h1><%= @user.name %></h1>
<p><%= @user.email %></p>
<!-- Vue: Reaktives Client-Rendering -->
<h1>{{ user.name }}</h1>
<p>{{ user.email }}</p>Text-Interpolation mit {{ }}
Die einfachste Form der Datenbindung ist die Text-Interpolation mit der „Mustache"-Syntax (doppelte geschweifte Klammern). Der Inhalt wird als reiner Text eingefügt und automatisch escaped — genau wie <%= %> in ERB.
<script setup>
import { ref } from 'vue'
const nachricht = ref('Hallo Vue!')
const anzahl = ref(42)
</script>
<template>
<p>{{ nachricht }}</p>
<p>Anzahl: {{ anzahl }}</p>
<p>Typ: {{ typeof anzahl }}</p>
</template>Automatisches Escaping
Vue escaped automatisch alle interpolierten Werte. Das bedeutet, dass HTML-Tags als Text angezeigt werden, nicht als HTML gerendert. Das schützt dich vor XSS-Angriffen — genau wie <%= %> in Rails (im Gegensatz zu <%== %>).
Raw HTML mit v-html
Manchmal möchtest du echtes HTML rendern, z.B. wenn du formatierten Text aus einer API bekommst. Dafür gibt es die v-html-Direktive.
<script setup>
import { ref } from 'vue'
const htmlInhalt = ref('<strong>Fetter Text</strong> und <em>kursiver Text</em>')
</script>
<template>
<!-- Escaped: zeigt die HTML-Tags als Text -->
<p>Escaped: {{ htmlInhalt }}</p>
<!-- Raw: rendert das HTML -->
<p>Raw: <span v-html=\"htmlInhalt\"></span></p>
</template>Vorsicht mit v-html!
Verwende v-html niemals mit Benutzereingaben! Es umgeht Vues Escaping und macht deine App anfällig für XSS-Angriffe. In Rails entspricht das <%== %> oder raw() — dort gilt die gleiche Warnung.
Attribute Binding mit v-bind
Mustache-Syntax funktioniert nicht innerhalb von HTML-Attributen. Stattdessen verwendest du v-bind, um Attribute dynamisch zu binden. Die Kurzschreibweise ist ein Doppelpunkt (:).
<script setup>
import { ref } from 'vue'
const bildUrl = ref('/images/vue-logo.png')
const istDeaktiviert = ref(true)
const inputId = ref('email-feld')
</script>
<template>
<!-- Langform -->
<img v-bind:src=\"bildUrl\" alt=\"Vue Logo\">
<!-- Kurzform (bevorzugt) -->
<img :src=\"bildUrl\" alt=\"Vue Logo\">
<!-- Boolean-Attribute -->
<button :disabled=\"istDeaktiviert\">Senden</button>
<!-- Dynamische ID -->
<input :id=\"inputId\" type=\"email\">
</template>Tipp: Kurzschreibweise verwenden
In der Praxis nutzt fast jeder die Kurzform :attribut statt v-bind:attribut. Du wirst sie in Dokumentation, Tutorials und Produktionscode überall sehen.
Mehrere Attribute gleichzeitig binden
Du kannst auch ein ganzes Objekt von Attributen auf einmal binden:
<script setup>
import { ref } from 'vue'
const inputAttrs = ref({
id: 'benutzername',
type: 'text',
placeholder: 'Dein Name',
class: 'form-input'
})
</script>
<template>
<!-- Alle Attribute werden auf das Element angewendet -->
<input v-bind=\"inputAttrs\">
</template>JavaScript-Ausdrücke in Templates
Vue unterstützt vollständige JavaScript-Ausdrücke innerhalb von Datenbindungen — nicht nur einfache Variablen.
<template>
<!-- Mathematik -->
<p>{{ preis * 1.19 }}</p>
<!-- Ternärer Operator -->
<p>{{ istAktiv ? 'Ja' : 'Nein' }}</p>
<!-- String-Methoden -->
<p>{{ nachricht.toUpperCase() }}</p>
<p>{{ name.split(' ').reverse().join(' ') }}</p>
<!-- Template-Literals -->
<p>{{ 'Hallo, ' + vorname + '!' }}</p>
<!-- Array-Methoden -->
<p>{{ items.filter(i => i.aktiv).length }} aktive Einträge</p>
</template>Nur Ausdrücke, keine Anweisungen!
Templates unterstützen nur Ausdrücke (expressions), die einen Wert zurückgeben. Folgendes funktioniert nicht:
<!-- ❌ Das sind Anweisungen, keine Ausdrücke -->
{{ let x = 1 }}
{{ if (ok) { return 'ja' } }}
<!-- ✅ Stattdessen: Ternärer Operator -->
{{ ok ? 'ja' : 'nein' }}Dynamische Attributnamen
Du kannst sogar den Namen eines Attributs dynamisch gestalten, indem du eckige Klammern verwendest:
<script setup>
import { ref } from 'vue'
const attributName = ref('href')
const eventName = ref('click')
</script>
<template>
<!-- Dynamischer Attributname -->
<a :[attributName]=\"'/about'\">Über uns</a>
<!-- Dynamischer Eventname -->
<button @[eventName]=\"handleEvent\">Klick mich</button>
</template>Wann braucht man das?
Dynamische Attribute sind nützlich für wiederverwendbare Komponenten, die verschiedene HTML-Elemente oder Events unterstützen müssen. Im Alltag brauchst du sie selten, aber es ist gut zu wissen, dass es geht.
Interaktive Demo
Probiere die Template-Syntax selbst aus! Tippe in das Eingabefeld und beobachte, wie sich alle Darstellungen reaktiv aktualisieren:
{{ nachricht }}
Hallo Vue! Schreibe **fett** für v-html.
{{ nachricht.toUpperCase() }}
HALLO VUE! SCHREIBE **FETT** FÜR V-HTML.
{{ nachricht.length }}
40 Zeichen
{{ nachricht.split(\'\').reverse().join(\'\') }}
.lmth-v rüf **ttef** ebierhcS !euV ollaH
v-html Beispiel
Hallo Vue! Schreibe fett für v-html.
Tipp: Schreibe **fett** um v-html zu testen
Zusammenfassung
Das Wichtigste auf einen Blick
{{ }}— Text-Interpolation (escaped, sicher)v-html— Raw HTML (Vorsicht: XSS-Gefahr!):attribut— Kurzform fürv-bind:attribut- JavaScript-Ausdrücke sind in allen Bindungen erlaubt
:[dynamisch]— Dynamische Attributnamen- Vue-Templates sind reaktiv, ERB-Templates nicht