Class & Style Binding
Vue bietet spezielle Erweiterungen für v-bind bei :class und :style. Neben Strings können auch Objekte und Arrays gebunden werden.
Class Binding: Objekt-Syntax
Abschnitt betitelt „Class Binding: Objekt-Syntax“Die Objekt-Syntax ermöglicht das bedingte Hinzufügen von Klassen:
<script setup>import { ref, computed } from 'vue'
const isActive = ref(true)const hasError = ref(false)</script>
<template> <!-- Einzelne Klasse --> <div :class="{ active: isActive }">...</div>
<!-- Mehrere Klassen --> <div :class="{ active: isActive, 'text-danger': hasError }">...</div>
<!-- Kombiniert mit statischer Klasse --> <div class="base-class" :class="{ active: isActive }">...</div>
<!-- Gebundenes Objekt --> <div :class="classObject">...</div></template>
<script setup>const classObject = computed(() => ({ active: isActive.value, 'text-danger': hasError.value}))</script>Class Binding: Array-Syntax
Abschnitt betitelt „Class Binding: Array-Syntax“Mit der Array-Syntax können mehrere Klassen dynamisch kombiniert werden:
<script setup>import { ref } from 'vue'
const activeClass = ref('active')const errorClass = ref('text-danger')const isActive = ref(true)</script>
<template> <!-- Array von Klassen --> <div :class="[activeClass, errorClass]">...</div>
<!-- Bedingt im Array --> <div :class="[isActive ? activeClass : '', errorClass]">...</div>
<!-- Objekt-Syntax im Array (kombiniert!) --> <div :class="[{ active: isActive }, errorClass]">...</div></template>Class Binding: Praxisbeispiele
Abschnitt betitelt „Class Binding: Praxisbeispiele“<script setup>import { ref } from 'vue'
const isLoading = ref(false)const isDisabled = ref(false)const variant = ref('primary')</script>
<template> <button class="btn" :class="{ 'btn--loading': isLoading, 'btn--disabled': isDisabled, [`btn--${variant}`]: true }" > <span v-if="isLoading">Laden...</span> <slot v-else /> </button></template><script setup>import { ref } from 'vue'
const currentTab = ref('home')const tabs = ['home', 'profile', 'settings']</script>
<template> <nav> <button v-for="tab in tabs" :key="tab" :class="['nav-tab', { 'nav-tab--active': currentTab === tab }]" @click="currentTab = tab" > {{ tab }} </button> </nav></template><script setup>import { ref, computed } from 'vue'
const email = ref('')const touched = ref(false)
const isValid = computed(() => /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email.value))</script>
<template> <input v-model="email" @blur="touched = true" :class="{ 'input--valid': touched && isValid, 'input--invalid': touched && !isValid }" /></template>Style Binding: Objekt-Syntax
Abschnitt betitelt „Style Binding: Objekt-Syntax“Inline-Styles können als Objekt gebunden werden:
<script setup>import { ref, reactive } from 'vue'
const activeColor = ref('red')const fontSize = ref(16)
const styleObject = reactive({ color: 'blue', fontSize: '14px', fontWeight: 'bold'})</script>
<template> <!-- Objekt-Syntax (camelCase) --> <div :style="{ color: activeColor, fontSize: fontSize + 'px' }">...</div>
<!-- Auch kebab-case möglich (mit Quotes) --> <div :style="{ 'font-size': fontSize + 'px' }">...</div>
<!-- Gebundenes Objekt --> <div :style="styleObject">...</div>
<!-- Array-Syntax (für mehrere Objekte) --> <div :style="[baseStyles, overrideStyles]">...</div></template>Style Binding: Array-Syntax
Abschnitt betitelt „Style Binding: Array-Syntax“Mit Arrays können mehrere Style-Objekte kombiniert werden:
<script setup>import { reactive } from 'vue'
const baseStyles = reactive({ padding: '10px', border: '1px solid #ccc'})
const highlightStyles = reactive({ backgroundColor: 'yellow', fontWeight: 'bold'})</script>
<template> <!-- Styles werden zusammengeführt --> <div :style="[baseStyles, highlightStyles]"> Kombinierte Styles </div></template>Auto-Prefixing
Abschnitt betitelt „Auto-Prefixing“Vue fügt automatisch Browser-Präfixe hinzu wenn nötig:
<template> <!-- Vue erkennt und präfixt automatisch --> <div :style="{ transform: 'rotate(45deg)' }">...</div> <!-- Wird zu: -webkit-transform, -ms-transform, transform --></template>Multiple Values (Fallback)
Abschnitt betitelt „Multiple Values (Fallback)“Für CSS-Properties können mehrere Werte als Array angegeben werden - der Browser verwendet den ersten unterstützten:
<template> <div :style="{ display: ['-webkit-box', '-ms-flexbox', 'flex'] }"> <!-- Browser verwendet den ersten unterstützten Wert --> </div></template>Praxisbeispiele
Abschnitt betitelt „Praxisbeispiele“<script setup>import { ref, computed } from 'vue'
const width = ref(200)const height = ref(150)
const boxStyle = computed(() => ({ width: `${width.value}px`, height: `${height.value}px`, backgroundColor: '#3b82f6', transition: 'all 0.3s ease'}))</script>
<template> <div :style="boxStyle" /> <input type="range" v-model="width" min="100" max="400" /> <input type="range" v-model="height" min="100" max="300" /></template><script setup>import { reactive } from 'vue'
const theme = reactive({ primary: '#3b82f6', secondary: '#10b981', background: '#ffffff', text: '#1f2937'})</script>
<template> <div :style="{ backgroundColor: theme.background, color: theme.text }"> <button :style="{ backgroundColor: theme.primary, color: 'white' }"> Primary Button </button> </div></template><script setup>import { ref } from 'vue'
const x = ref(0)const y = ref(0)
function onMouseMove(e) { x.value = e.clientX y.value = e.clientY}</script>
<template> <div @mousemove="onMouseMove" class="container"> <div class="follower" :style="{ transform: `translate(${x}px, ${y}px)`, position: 'absolute', transition: 'transform 0.1s ease-out' }" /> </div></template>Class vs Style Binding
Abschnitt betitelt „Class vs Style Binding“- Vordefinierte CSS-Klassen existieren
- Zustände getoggelt werden (active, disabled, etc.)
- Mit CSS-Frameworks gearbeitet wird (Tailwind, Bootstrap)
- Komplexe Styles mit Pseudo-Elementen/Media Queries nötig sind
- Bessere Wartbarkeit gewünscht ist
- Werte zur Laufzeit berechnet werden (Größen, Positionen)
- Farben dynamisch sind (Theme, User-Auswahl)
- Animationen mit JS-Werten gesteuert werden
- Einmalige, spezifische Styles nötig sind
- CSS Custom Properties gesetzt werden
Kombination mit v-bind() in CSS
Abschnitt betitelt „Kombination mit v-bind() in CSS“Seit Vue 3.2 können reaktive Werte auch direkt im <style>-Block verwendet werden:
<script setup>import { ref } from 'vue'
const color = ref('blue')const size = ref(16)</script>
<template> <p class="dynamic-text">Dynamisch gestyled</p></template>
<style scoped>.dynamic-text { color: v-bind(color); font-size: v-bind(size + 'px');}</style>Best Practices
Abschnitt betitelt „Best Practices“- Verwende
:classfür wiederverwendbare Styles - Nutze computed Properties für komplexe Klassen-Logik
- Kombiniere statische und dynamische Klassen
- Verwende aussagekräftige Klassennamen
- Vermeide zu viele Inline-Styles (schwer wartbar)
- Keine komplexe Logik direkt im Template
- Nicht
:classundclassmit überlappenden Klassen mischen - Keine Magic Numbers in Styles
Dokumentation
Abschnitt betitelt „Dokumentation“Offizielle Vue Dokumentation:
- Class and Style Bindings - Vollständige Referenz
- Binding HTML Classes
- Binding Inline Styles