VueUse in der Praxis: Composables für den Alltag richtig einsetzen
AI generated
<v/>
{ }
VueUse · Composables · Vue 3 · Composition API
VueUse in der Praxis
Composables für den Alltag richtig einsetzen

VueUse bündelt über zweihundert fertige Composables für Storage, Sensoren, Zeitgeber und Browser-APIs. Wer diese Bibliothek gezielt statt pauschal einsetzt, spart nicht nur Zeit beim Schreiben eigener Utility-Funktionen, sondern reduziert auch Bugs bei Edge-Fällen wie SSR, Cleanup und Reaktivität, die in selbst geschriebenen Composables leicht übersehen werden.

15 Min. Lesezeit useStorage · useFetch · useEventListener · Custom Composables Vue 3 · Nuxt 3 · Vite

1. Was VueUse wirklich löst

VueUse ist eine Sammlung von mehr als zweihundert Composition API Funktionen, die typische Aufgaben aus dem Frontend-Alltag als fertige, gut getestete Composables bereitstellen. Statt für Local Storage, Fenstergröße, Maus-Position oder Debouncing jedes Mal eine eigene kleine Utility-Funktion zu bauen, importiert man den passenden Composable aus VueUse und bindet ihn direkt in die Komponente ein. Der Vorteil liegt nicht nur in der eingesparten Zeit, sondern vor allem in der Qualität: VueUse deckt Edge-Fälle ab, die in schnell geschriebenen Eigenimplementierungen regelmäßig übersehen werden.

Ein typisches Beispiel ist die Synchronisation von Zustand mit Local Storage. Auf den ersten Blick wirkt das trivial, doch sobald mehrere Tabs gleichzeitig geöffnet sind, Server Side Rendering ins Spiel kommt oder der gespeicherte Wert kein einfacher String ist, entstehen schnell Bugs. VueUse hat diese Fälle bereits gelöst, getestet und dokumentiert. Wer VueUse in ein Projekt einbindet, ersetzt damit potenziell dutzende kleine, fehleranfällige Hilfsfunktionen durch eine einzige, konsistente Bibliothek mit einheitlicher API.

Der zweite große Vorteil von VueUse ist die Konsistenz der API selbst. Fast jede Funktion folgt demselben Muster: Ein oder mehrere reaktive Refs werden zurückgegeben, oft ergänzt um Steuerfunktionen wie pause, resume oder trigger. Wer einmal verstanden hat, wie useMouse funktioniert, versteht auch die Grundstruktur von useElementSize oder useWindowScroll, weil VueUse konsequent auf denselben Composable-Konventionen aufbaut.

2. Installation, Tree-Shaking und Bundle-Größe

Die Installation von VueUse erfolgt über einen einzigen Paketbefehl, npm install @vueuse/core, und funktioniert sowohl in reinen Vue-3-Projekten als auch in Nuxt-3-Anwendungen. Für Nuxt gibt es zusätzlich das offizielle Modul @vueuse/nuxt, das Auto-Imports für alle VueUse-Funktionen aktiviert, sodass kein manueller Import mehr nötig ist. In klassischen Vite-Projekten importiert man Composables gezielt aus @vueuse/core, was gleichzeitig der Schlüssel zu kleinem Bundle ist.

VueUse ist konsequent auf Tree-Shaking ausgelegt. Jede Funktion ist ein eigenständiges ES-Modul, sodass Bundler wie Rollup oder esbuild nur den Code der tatsächlich importierten Composables in das finale Bundle aufnehmen. Wer nur useStorage und useMouse importiert, zahlt nicht die Bundle-Größe der gesamten VueUse Bibliothek, sondern nur die dieser beiden Funktionen plus ihrer internen Abhängigkeiten. Das unterscheidet VueUse deutlich von monolithischen Utility-Bibliotheken, die häufig komplett gebündelt werden.

Ein häufiger Stolperstein ist der Import aus dem falschen Paket. Neben @vueuse/core existieren spezialisierte Pakete wie @vueuse/router, @vueuse/firebase oder @vueuse/motion, die zusätzliche Peer-Dependencies benötigen. Wer VueUse produktiv einsetzt, sollte diese Aufteilung kennen, um nicht versehentlich unnötige Abhängigkeiten in das Projekt zu ziehen.

3. State-Composables: useStorage und Co

Der wohl meistgenutzte VueUse Composable ist useStorage. Er bindet einen reaktiven Ref direkt an Local Storage oder Session Storage, inklusive automatischer Serialisierung von Objekten, Arrays, Zahlen und Booleans. Änderungen am Ref werden automatisch persistiert, und Änderungen im Storage selbst, etwa durch ein anderes Browser-Tab, werden über das storage-Event zurück in den Ref gespiegelt. Das macht VueUse zur naheliegenden Wahl für Einstellungen, Theme-Präferenzen oder Formular-Entwürfe, die den Reload überleben sollen.

useLocalStorage und useSessionStorage sind spezialisierte Varianten von useStorage mit vorkonfiguriertem Storage-Backend. Alle drei Composables unterstützen einen dritten Parameter für einen Standardwert sowie Optionen wie mergeDefaults, das beim ersten Laden fehlende Schlüssel eines gespeicherten Objekts automatisch mit dem Standardwert ergänzt, ohne bestehende Werte zu überschreiben. Das ist besonders bei Konfigurationsobjekten hilfreich, die sich über Versionen des Projekts hinweg erweitern.


// State-Composables: persistent settings with useStorage
import { useStorage } from '@vueuse/core'

// Object is automatically (de)serialized as JSON
const settings = useStorage('app-settings', {
  theme: 'dark',
  fontSize: 16,
  notifications: true,
})

// Any mutation is written back to localStorage immediately
settings.value.fontSize = 18

// mergeDefaults keeps existing keys, adds new ones on schema change
const prefs = useStorage(
  'user-prefs',
  { locale: 'de', layout: 'grid' },
  localStorage,
  { mergeDefaults: true },
)

// Session-scoped variant survives reload but not tab close
import { useSessionStorage } from '@vueuse/core'
const draftText = useSessionStorage('draft-comment', '')

4. Sensor-Composables: Maus, Elementgröße, Sichtbarkeit

Eine zweite große Gruppe von VueUse Composables kapselt Browser-Sensoren, also Werte, die sich laufend ändern und normalerweise über Event Listener beobachtet werden müssten. useMouse liefert die aktuelle Mausposition als reaktive Refs, useElementSize beobachtet Breite und Höhe eines Elements über einen ResizeObserver, und useWindowSize liefert die Fenstergröße. Alle drei aktualisieren sich automatisch, ohne dass eigener Event-Handling-Code geschrieben werden muss.

Besonders wertvoll ist useIntersectionObserver, weil es eine der komplexeren Browser-APIs auf eine einzige Composable-Funktion reduziert. Lazy Loading von Bildern, Infinite Scroll oder das Nachladen von Inhalten beim Erreichen eines Sentinel-Elements lassen sich damit ohne manuelles Observer-Setup und ohne manuelles Aufräumen umsetzen. VueUse übernimmt das Erstellen, Beobachten und das Disconnect beim Unmount der Komponente automatisch.


// Sensor composables: element size and visibility tracking
import { useElementSize, useIntersectionObserver } from '@vueuse/core'
import { ref } from 'vue'

const cardRef = ref(null)
const { width, height } = useElementSize(cardRef)

// Fires whenever the target enters or leaves the viewport
const sentinelRef = ref(null)
const { stop } = useIntersectionObserver(
  sentinelRef,
  ([{ isIntersecting }]) => {
    if (isIntersecting) {
      loadNextPage()
    }
  },
  { threshold: 0.1 },
)

// stop() detaches the observer manually if needed before unmount

5. Async-Composables: useFetch, useAsyncState, refDebounced

Für asynchrone Datenbeschaffung bietet VueUse mit useFetch einen Composable, der Ladezustand, Fehlerzustand und Antwortdaten als reaktive Refs zurückgibt, inklusive Unterstützung für Abbruch über AbortController bei erneutem Aufruf und automatischem Refetch bei Änderung reaktiver URL-Parameter. Damit deckt VueUse einen großen Teil dessen ab, wofür man sonst eine dedizierte Datenbeschaffungs-Bibliothek einsetzen würde, ohne zusätzliche Abhängigkeit.

useAsyncState ist die allgemeinere Variante: Sie nimmt eine beliebige asynchrone Funktion entgegen, nicht nur einen Fetch-Aufruf, und liefert ebenfalls isLoading, error und state zurück. Für Eingabefelder, die nicht bei jedem Tastendruck einen Request auslösen sollen, kombiniert man VueUse häufig mit refDebounced oder refThrottled, die einen Ref-Wert verzögert beziehungsweise gedrosselt weiterreichen, ohne dass man selbst einen Timer verwalten muss.


// Async composables: debounced search with useFetch
import { useFetch, refDebounced } from '@vueuse/core'
import { ref, computed } from 'vue'

const searchInput = ref('')
const debouncedSearch = refDebounced(searchInput, 400)

const url = computed(() => `/api/products?q=${debouncedSearch.value}`)

// Refetches automatically whenever the computed URL changes
const { data: products, isFetching, error } = useFetch(url, {
  refetch: true,
}).json()

6. Browser-APIs sauber kapseln

Ein weiterer Kernbereich von VueUse sind Wrapper um Browser-APIs, die sonst mit viel Boilerplate verbunden wären. useClipboard kapselt die Clipboard API inklusive Feature-Detection und einem copied-Flag, das sich nach kurzer Zeit automatisch zurücksetzt, ideal für "Kopiert"-Feedback an Buttons. usePermission fragt den Berechtigungsstatus von Browser-APIs wie Kamera, Mikrofon oder Geräteposition ab und bleibt dabei reaktiv, wenn sich der Status während der Session ändert.

useEventListener ist einer der unscheinbarsten, aber am häufigsten verwendeten VueUse Composables. Er registriert einen Event Listener und entfernt ihn automatisch beim Unmount der Komponente, ganz ohne expliziten onUnmounted-Hook im aufrufenden Code. Gerade bei globalen Listenern auf window oder document verhindert das die klassische Fehlerquelle vergessener Cleanup-Aufrufe, die zu Memory Leaks in Single Page Applications führen.


// Browser API wrappers: clipboard and global event listener
import { useClipboard, useEventListener } from '@vueuse/core'
import { ref } from 'vue'

const { copy, copied, isSupported } = useClipboard()

async function copyShareLink(url) {
  if (isSupported.value) {
    await copy(url)
    // "copied" resets to false automatically after a short delay
  }
}

// Cleanup is handled automatically on unmount, no onUnmounted needed
useEventListener(window, 'keydown', (event) => {
  if (event.key === 'Escape') {
    closeActiveModal()
  }
})

7. Eigene Composables im VueUse-Stil bauen

Wer die Konventionen von VueUse verinnerlicht hat, kann eigene Composables im selben Stil bauen und so die Codebasis eines Projekts konsistent halten. Zentrale Hilfsfunktionen aus VueUse selbst helfen dabei: tryOnScopeDispose registriert eine Cleanup-Funktion, die auch außerhalb einer Komponente in einem effectScope funktioniert, und createSharedComposable wandelt einen normalen Composable in eine Singleton-Variante um, die von allen aufrufenden Komponenten denselben reaktiven Zustand teilt.

Das ist besonders nützlich für Dinge wie die Online/Offline-Erkennung oder die Fenstergröße, bei denen jede Komponente denselben Wert braucht, aber nicht jede Komponente ihren eigenen Event Listener registrieren sollte. Mit createSharedComposable teilt sich die gesamte Anwendung eine einzige Instanz des zugrundeliegenden Listeners, unabhängig davon, wie viele Komponenten den Composable aufrufen. VueUse selbst nutzt dieses Muster intern für mehrere seiner globalen Composables.


// Building a custom composable in VueUse style
import { ref, onScopeDispose } from 'vue'
import { createSharedComposable, useEventListener } from '@vueuse/core'

function useOnlineStatusRaw() {
  const isOnline = ref(navigator.onLine)

  useEventListener(window, 'online', () => { isOnline.value = true })
  useEventListener(window, 'offline', () => { isOnline.value = false })

  return { isOnline }
}

// Shared across the whole app: one listener, many consumers
export const useOnlineStatus = createSharedComposable(useOnlineStatusRaw)

8. Typische Fehler und SSR-Fallstricke

Der häufigste Fehler beim Einsatz von VueUse betrifft Server Side Rendering. Composables wie useWindowSize oder useStorage greifen auf window beziehungsweise localStorage zu, Objekte, die während des Server-Renderings in Nuxt schlicht nicht existieren. VueUse behandelt die meisten dieser Fälle bereits intern und liefert sinnvolle Fallback-Werte, aber wer eigene Composables im VueUse-Stil schreibt, muss diese Prüfung selbst nachbauen, etwa mit typeof window !== 'undefined' vor jedem direkten Browser-API-Zugriff.

Ein zweiter Fehler ist das versehentliche Destrukturieren reaktiver Rückgabewerte ohne toRefs oder direkte Ref-Zuweisung. VueUse gibt fast überall bereits einzelne Refs zurück, sodass normales Destrukturieren funktioniert, doch bei Composables, die ein reaktives Objekt statt einzelner Refs zurückliefern, geht die Reaktivität beim Destrukturieren verloren. Ein dritter, subtilerer Fehler entsteht, wenn VueUse Composables außerhalb des Setup-Kontexts einer Komponente aufgerufen werden, etwa in einer normalen Utility-Funktion, wodurch Lifecycle-Hooks wie das automatische Cleanup nicht greifen.

9. VueUse-Funktionen im Vergleich

Nicht jede Aufgabe braucht denselben VueUse Composable, und die Wahl der richtigen Funktion hat direkten Einfluss auf Performance und Korrektheit. Die folgende Übersicht zeigt gängige Aufgaben und den jeweils passenden VueUse Composable im Vergleich zur manuellen Eigenimplementierung.

Aufgabe Manuell (aufwendig) VueUse Composable Vorteil
State in Local Storage Eigener watch plus JSON.parse useStorage Cross-Tab-Sync, Serialisierung inklusive
Elementgröße beobachten Eigener ResizeObserver plus Cleanup useElementSize Automatisches Disconnect beim Unmount
Verzögerte Sucheingabe Eigener setTimeout-Debounce refDebounced Reaktiv, getestet, konfigurierbar
In Zwischenablage kopieren Manuelle Clipboard-API plus Fallback useClipboard Feature-Detection, Copied-Flag inklusive
Globaler Event Listener onMounted plus onUnmounted manuell useEventListener Automatisches Cleanup, ein Aufruf

Diese Gegenüberstellung macht deutlich, dass VueUse nicht primär Zeilen Code spart, sondern vor allem Fehlerquellen eliminiert, die bei der manuellen Umsetzung immer wieder auftauchen: vergessenes Cleanup, fehlende Feature-Detection und übersehene SSR-Fälle. Genau deshalb setzen viele Vue-Teams VueUse mittlerweile standardmäßig in jedem neuen Projekt ein.

Mironsoft

Vue 3, Nuxt 3 und moderne Frontend-Architektur

Vue-Projekt mit sauberen Composables statt Copy-Paste-Code?

Wir bauen Vue- und Nuxt-Anwendungen mit VueUse und eigenen Composables im selben Stil auf, prüfen bestehende Codebasen auf SSR-Fallstricke und Memory Leaks und richten eine wartbare Composable-Architektur für euer Team ein.

Composable-Audit

Bestehende Composables auf SSR-Sicherheit und Cleanup prüfen

VueUse-Integration

Passende VueUse-Funktionen auswählen und Bundle-Größe im Blick behalten

Eigene Composables

Wiederverwendbare Composables im VueUse-Stil für euer Projekt entwickeln

10. Zusammenfassung

VueUse ersetzt selbst geschriebene Utility-Composables durch getestete, tree-shakable Funktionen, die typische Aufgaben wie Storage-Synchronisation, Sensor-Beobachtung, asynchrone Datenbeschaffung und Browser-API-Zugriff einheitlich lösen. Composables wie useStorage, useElementSize, useFetch und useEventListener decken einen großen Teil des Frontend-Alltags ab, ohne dass jedes Team dieselben Edge-Fälle erneut selbst debuggen muss.

Wer die Konventionen von VueUse versteht, kann mit Hilfsfunktionen wie createSharedComposable und tryOnScopeDispose eigene Composables im selben, konsistenten Stil bauen. Wichtig bleibt dabei die Aufmerksamkeit für SSR-Fallstricke und korrekte Cleanup-Logik, denn genau diese Details sind der eigentliche Mehrwert, den VueUse gegenüber einer schnellen Eigenimplementierung bietet.

VueUse in der Praxis, das Wichtigste auf einen Blick

Installation

@vueuse/core für Vue, @vueuse/nuxt für Auto-Imports in Nuxt 3. Tree-Shaking hält das Bundle klein.

State & Storage

useStorage synchronisiert Refs automatisch mit Local Storage, inklusive Cross-Tab-Updates.

Sensoren & Async

useElementSize, useIntersectionObserver und useFetch kapseln Browser-APIs reaktiv.

Eigene Composables

createSharedComposable für Singleton-Zustand, tryOnScopeDispose für sicheres Cleanup.

11. FAQ: VueUse in der Praxis

1Was ist VueUse?
Über zweihundert Composition API Funktionen für Vue 3, die typische Aufgaben als fertige, getestete Composables bereitstellen.
2Erhöht VueUse die Bundle-Größe?
Nein, dank konsequentem Tree-Shaking bindet der Bundler nur die tatsächlich importierten Funktionen ein.
3Funktioniert VueUse mit Nuxt 3 SSR?
Ja, mit @vueuse/nuxt und Auto-Imports. Die meisten Composables behandeln SSR-Fälle bereits intern.
4Was macht useStorage besonders?
Automatische Serialisierung, Cross-Tab-Synchronisation und mergeDefaults für Schema-Erweiterungen.
5Wofür createSharedComposable?
Wandelt einen Composable in eine Singleton-Variante um, die Zustand und Listener über alle Komponenten teilt.
6VueUse mit Vue 2 nutzen?
Dafür existiert eine separate Version auf Basis von @vue/composition-api. Die Hauptversion ist Vue 3 exklusiv.
7useFetch vs. useAsyncState?
useFetch ist HTTP-spezifisch mit Abbruch und Refetch. useAsyncState nimmt jede asynchrone Funktion entgegen.
8Manuelles Aufräumen bei useEventListener?
Nicht nötig, der Listener wird automatisch beim Unmount der Komponente entfernt.
9Warum geht Reaktivität manchmal verloren?
Meist durch Destrukturieren ohne toRefs oder Aufruf außerhalb des Setup-Kontexts einer Komponente.
10Lohnt sich VueUse für kleine Projekte?
Ja, dank Tree-Shaking spart bereits ein einzelner Composable Boilerplate-Code und potenzielle Bugs ein.