Zum Inhalt springen

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.

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>

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>
<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>

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>

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>

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>

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>
<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>
  • 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

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>
  • Verwende :class fü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 :class und class mit überlappenden Klassen mischen
  • Keine Magic Numbers in Styles

Offizielle Vue Dokumentation: