Tutorials |

Vue clever nutzen – Wiederverwendbarkeit für Einsteiger:innen

Peerigon Member

Lea

4. April 2025

tl;dr quick summary
In diesem Artikel zeigen wir dir, wie du Vue-Anwendungen von Anfang an sauber und wartbar aufbaust – mit einem praxisnahen Einstieg in das Thema Wiederverwendbarkeit. Du erfährst, wann sich der Einsatz von Komponenten, Composables, Stores oder Utility Functions lohnt, um deinen Code schlanker, performanter und DRY(er) zu machen.

Intro

Einer der wichtigsten Aspekte bei sauberem, wartbarem Code ist die Wiederverwendbarkeit, oder wie viele Entwickler:innen sagen, das DRY-Prinzip (Don't Repeat Yourself). Durch die Wiederverwendung von Code muss weniger Code gepflegt werden, was dazu führt, dass der Code weniger fehleranfällig ist. Dies gilt für alle Arten von Programmieren, unabhängig von der Technologie oder dem Framework. Und es gilt wahrscheinlich auch für eine Menge anderer Berufe. Heute sprechen wir speziell über ein Framework: Vue.js. Dieser Artikel wird sich nicht darauf konzentrieren, warum oder wann man wiederverwendbaren Code verwenden sollte. Stattdessen wird erklärt, welchen Ansatz man in Vue verwenden sollte.

Four panel meme. The first row shows Drake in a disapproving pose, the text next to it says "Writing new code". The second row shows Drake smiling and pointing at a text that says "Reusing code because it's good for maintainability"

Dieser Beitrag wurde hauptsächlich für Einsteiger:innen geschrieben, weil viele dieser Prinzipien nicht neu oder bahnbrechend sind. Eigentlich sollte man sie kennen, wenn man schon ein wenig entwickelt hat. Aber da die Realität nicht perfekt ist, habe ich schon einiges an Code gesehen, der diese Richtlinien nicht befolgt. Dies ist also hauptsächlich für die folgenden Personen gedacht:

  • Anfänger:innen, die neu in der Entwicklung mit Frameworks sind
  • Leute, die von anderen Frameworks kommen und in die Entwicklung von Vue einsteigen wollen
  • Wenn man sich einfach nicht sicher ist, welches wiederverwendbare Konzept man verwenden sollte
  • Um einen Link an jemanden zu schicken, der:die diese Praktiken nicht befolgt :)

Vue ist ein opinionated Framework und gibt uns mehrere Möglichkeiten zur Wiederverwendung von Code. Die Beispiele in diesem Blog nutzen die Vue Composition API. Nicht alle der Ansätze sind für jedes Szenario geeignet. Beginnen wir mit der offensichtlichsten: Komponenten.

Komponenten - Die Offensichtlichen

Wir alle haben schon Komponenten verwendet. Und wenn du noch keine verwendet hast, was tust du? Der Schlüssel für ein konsistentes Verhalten in der gesamten Anwendung ist die Verwendung von Komponenten, die kleine Teile der Benutzeroberfläche kapseln. Komponenten werden oft nach den Prinzipien des Atomic Design geschrieben. Es gibt Atome wie Buttons, Eingabefelder oder Icons, dann Moleküle wie Suchfelder, Organismen, die aus diesen aufgebaut sind und so weiter. Vue verwendet Single File Components (SFCs), die Template, Script und Style in einer Datei kapseln. Vue fordert, dass eine SFC mindestens ein Template- oder ein Script-Tag hat. Wann sollte man also Komponenten für wiederverwendbare Logik verwenden?

Sasuke standing in a circle completely surrounded by Naruto clones. The inner text says "Vue", the one by the Naruto clones says "Components"

Komponenten sollten immer einen bestimmten Teil der UI implementieren, d.h.:

  • Eine Komponente sollte immer ein Template-Tag haben
  • Die Logik in der Komponente sollte nirgendwo anders wiederverwendet werden müssen
  • Das Styling sollte in der Komponente gescoped sein

Die Namenskonvention für Komponenten in Vue sind zusammengesetzte Wörter.

Beispiele: TextButton, ReadonlyTable, TextInput, ModalDialog, SectionWrapper, CustomForm

Scoped Styling ist ein Segen, und sollte wann immer möglich verwendet werden. Das Styling zu scopen bedeutet, dass es nur auf die Komponente angewandt wird, in der es definiert wird und nicht andere Komponenten beeinflusst. Es macht die Wiederverwendung von Komponenten so viel einfacher, weil man weiß, welches Styling man zu erwarten hat. Denn niemand will der großen Frage nachgehen: Warum ist das nicht zentriert? Manchmal ist es unvermeidlich, das Styling von untergeordneten Komponenten anzupassen. In solchen Fällen sollte :deep(.class) verwendet werden, damit die Änderung nicht global für die gesamte Anwendung gilt, sondern nur für diese Komponente und die darunter liegenden Komponenten im Abhängigkeitsbaum.

Ein weiteres Konzept für Komponenten, welches die Wiederverwendung so einfach macht, sind „Slots“. Eine übergeordnete Komponente kann einer untergeordneten Komponente HTML-Inhalt übergeben, der anstelle des Slot-Tags gerendert wird. Nicht alle Komponenten benötigen dies, aber auf diese Weise kann man sogar Containerkomponenten bauen, wie einen Wrapper für eine Karte oder ein Modal. Komponenten können lokal oder global importiert werden. Wenn man sich unsicher ist, sollte man immer lokale Importe bevorzugen. Auf diese Weise wird der Code nur in das Bundle aufgenommen, wenn er gebraucht wird. Globale Importe sind nur dann sinnvoll, wenn offensichtlich ist, dass sie in vielen Komponenten benötigt werden. Meistens werden sie nur zum Einbinden von Bibliotheken verwendet. Man kann auch allgemeine Basiskomponenten einbinden, wenn man der Meinung ist, dass deren expliziter Import die Menge an Code zu sehr vergrößert. (Ich mache das ehrlich gesagt nie, aber ich möchte auch niemandem auf die Füße treten, der das tut. Tu, was du für richtig hältst.)

Das folgende Beispiel zeigt eine einfache Implementierung eines Buttons in Aktion.

Composables - Das Ausgefallene

Einige Leute könnten jetzt argumentieren, dass man eine Komponente ohne Template-Tag schreiben und stattdessen nur ein Script-Tag verwenden kann. Das wird immer noch kompiliert und ist per se nicht falsch. Aber es gibt etwas Passenderes: Composables. Ein Composable ist eine Datei, die eine Funktion mit Logik exportiert. Wer bereits mit Vue 2 programmiert hat, kennt vielleicht die alte Variante dieses Konzepts, die Mixins genannt wurde. Da Mixins eine Menge Probleme hatten, wurde mit Vue 3 diese neue Variante eingeführt. Ein Composable enthält nur Logik, keine Templates oder Styling. Wenn diese nicht benötigt werden, sollte immer ein Composable gegenüber einer Komponente mit nur einem Script-Tag bevorzugt werden. Der Grund dafür ist, dass Composables nicht den Overhead einer renderlosen Komponenteninstanz benötigen. Jede Komponente hat einen Lebenszyklus und verfolgt die Reaktivität, während ein Composable einfach eine JavaScript-Funktion ist, die die Reaktivität nur für die von ihr verwendeten reaktiven Variablen benötigt.

A four panel meme. The first row shows a tired and bored Winnie Pooh and the text "Renderless Components". The second row shows a smug looking Winnie Pooh with a tuxedo and the text "Composables" next to it.

Du solltest ein Composable verwenden, wenn:

  • Wiederverwendbare Logik benötigt wird
  • Es keinen Grund für Templates oder Styling gibt
  • Man einen State für diese Logik verwalten müssen (wir werden später über stateless Logik sprechen)
  • Du Vue-API-Methoden* verwenden möchtest
  • Der State nicht zwischen Komponenten geteilt werden sollte, die das gleiche Composable verwenden

Lass uns ein wenig mehr über den letzten Punkt sprechen. Einige kleine Anwendungen möchten vielleicht ihre Fetchlogik ohne eine Bibliothek verwalten und schreiben dafür ein Composable useFetch. Die Datei hat einen Parameter query und exportiert das Ergebnis und den Ladezustand. Das Composable kann in jeder Datei verwendet werden, in der eine Anfrage ans Backend gesendet werden soll. Aber jede Verwendung sollte das Ergebnis der Abfrage, nach der sie gefragt haben, und den Ladezustand für diese Abfrage zurückgeben. Wenn ComponentA mit dem Composable loading: true erhält, kann ComponentB die Anfrage bereits abgeschlossen haben und loading: false anzeigen. Selbst wenn beide Komponenten gleichzeitig denselben Parameter benutzen, bleiben sie getrennt. Das bedeutet, dass jede Verwendung eines Composables auf die Komponente eingeschränkt ist. Der Nachteil ist, dass sie für die Composition API geschrieben sind. Das bedeutet, dass man eine Setup-Funktion benötigt, um sie einbinden zu können. Man kann auch einen setup-Hook zur Options-API hinzufügen, aber man sollte sich bewusst sein, dass die Initialisierung von data nach Setup erfolgt. Die Namenskonvention für Composables ist useSomething.

Beispiele: useFetch, useMouse, useCalculation

Vue pflegt auch eine große Sammlung von nützlichen Composition-Utilities, die als Composables unter VueUse eingesetzt werden. Ziehe in Erwägung, diese zu verwenden, bevor du grundlegende Composables schreibst, wie z.B. die Verwendung von localStorage, die Browser API oder mathematische Berechnungen.

Hier kannst du ein Beispiel in Aktion sehen. Das Ziel ist es, ein wiederverwendbares Composable zu haben, das ein HTML Element erhält und dessen Größe zurückgibt.

Store - Der Geteilte

Wir haben gerade über stateful Logik gesprochen, die auf eine Anwendung beschränkt ist. Manchmal muss der State aber über Komponenten, Seiten und Composables hinweg gemeinsam genutzt werden. Das Nutzen von Composables könnte zu unnötigem Performance-Overhead und Speicherlecks führen. Wenn du z.B. ein Composable schreibst, um die Zeit zu tracken, musst du setInterval verwenden, um Updates für die aktuelle Uhrzeit zu erhalten. Wenn man dafür ein Composable verwendet, instanziiert man es für jede einzelne Komponente, die es verwendet. Stattdessen sollte das nur einmal geschehen und in der gesamten Anwendung wiederverwendet werden können. Um dies zu tun, sollte man einen Store verwenden. Vue empfiehlt Pinia für das State Management. Längere Nutzer:innen kennen vielleicht VueX, den Vorgänger dazu. Man kann Logik in einen Store einbinden, aber um das Prinzip der Separation of Concerns zu wahren, sollte sie mit dem State gekoppelt sein. Behalte die Logik, die sich auf den State bezieht, innerhalb des Stores, aber extrahiere komplexe, wiederverwendbare Logik in Composables. Um Vue API Funktionen wie z.B. watchEffect zu verwenden, kann Pinias Setup Store Syntax verwendet werden.

Ein Store sollte verwendet werden für:

  • Geteilten State

Die Namenskonvention für Stores ist:

  • useContentStore für die exportierte Funktion des Stores
  • content.js für die Datei, die den Store enthält

Beispiele: userStore, sessionStore

Utils - Die Klassiker

Um unsere Grundlagenliste zu vervollständigen, fehlt noch die Möglichkeit, stateless Logik wiederzuverwenden. Vue implementiert dafür keine spezielle Funktionalität. Wie in anderen Projekten und bei der Arbeit ohne Framework, sollte stateless Logik in Utility-Dateien gehalten werden. Utility-Funktionen sind unabhängig von Vues Reaktivitätssystem. Es können auch Bibliotheken für diese Funktionen genutzt werden, anstatt sie selbst zu schreiben. Viele Projekte benutzen lodash für Utilities oder date-fns, um mit Daten zu arbeiten.

Utils sind perfekt für:

  • Stateless Logik
  • Wenn keine Vue-API-Funktionen benötigt werden
  • Grundsätzlich Funktionen, die eine Eingabe erhalten und eine Ausgabe zurückgeben

Beispiele: sortByCustom, calculateX, formatToY

Zusammenfassung

Die Wahl des richtigen Wiederverwendbarkeitskonzepts in Vue ist der Schlüssel zum Schreiben von wartbarem, skalierbarem und effizientem Code. Komponenten handhaben UI-Elemente, Composables verwalten wiederverwendbare Logik, Stores verwalten geteilte States und Utility-Funktionen vereinfachen stateless Operationen. Unten ist eine Tabelle, die die Unterschiede in der Nutzung auf visuelle Weise zusammenfasst. Nicht alles davon ist in Stein gemeißelt, sie sollten dir aber bewusst sein. Wenn man gegen diese Richtlinien verstoßen will, sollte es einen triftigen Grund dafür geben.

KomponentenComposablesStoreUtils
HTML/Template
Beinhaltet Styling🆗
Implementiert Logik🆗🆗
Nutzt Vue API functions*🆗🆗🆗
Geteilter State
Reaktivität🆗
Idealer AnwendungsfalleUI ElementeWiederverwendbare LogikGeteilter StateReine Funktionen

✅ = ja ❌ = nein 🆗 = optional

*Exporte wie ref und reactive, Compiler-Makros wie defineProps, oder Helfer wie watch sowie Hooks usw.

Wie man sehen kann, gibt es für die verschiedenen Konzepte spezifische Anwendungsfälle. Die Verwendung des richtigen Konzepts erhöht die Leistung und sorgt für einen sauberen und wartbaren Code, den auch andere verstehen können. Die meisten dieser Konzepte ähneln denen anderer Frameworks. Komponenten sind ein gängiges Konzept. Composables sind zum Beispiel die gleiche Idee wie Hooks in React. Und obwohl es in diesem Artikel um Wiederverwendbarkeit geht, können all diese Konzepte auch dann genutzt werden, wenn der Code nicht wiederverwendet werden soll und Dateien einfach in kleinere, besser lesbare Dateien aufgeteilt werden sollen. Zu wissen, wann man seinen Code aufteilen sollte, erfordert etwas Übung, aber das Verständnis dieser Grundkonzepte ist der erste Schritt, um die Theorie in der Praxis anwenden zu können.

Vue

JavaScript

Reusability

DRY Principle

Components

Composables

Weitere Themen

Header-top-ten-mistakes-to-avoid.png

Francesca, Ricarda, 02.04.2025

Die 10 häufigsten Fehler bei der Entwicklung digitaler Produkte – und wie du sie vermeidest

MVP development

UX/UI design

product vision

agile process

user engagement

product development

Zum Blogartikel

Judith, 31.03.2025

Von der Hypothese zur echten Erkenntnis: MVPs richtig einsetzen

Zum Blogartikel
Three pupas, a new green chrysalis coloration, one that’s about ready to emerge, and a butterfly that’s already come out

Antony, 30.01.2025

Von Forms zu Mutations – wie sich Datenhandling in React weiterentwickelt hat

Forms

React

Mutations

Web App Development

Remix

Actions

Optimistic UI

Zum Blogartikel