Ist Vue.js noch ein Frontend Framework?! In den letzten Jahren gab es einen großen Hype um das neue JavaScript Framework. Die untere Grafik zeigt die Anzahl der Google Trends für Vue.js. Da ist es verständlich, dass es auf der Gegenseite auch Skeptiker gibt, die nicht schon wieder auf den neuesten Trend aufspringen möchten.
Um zu verstehen, woher der ganze Trubel kam, welche Probleme das Framework löst und ob es empfehlenswert ist, es einzusetzen, sollte man sich zuerst einmal mit der Frage auseinandersetzen, wie es überhaupt zu der sog. „Framework Hölle“ kommen konnte. Im weiteren Verlauf dieses Artikels geht es dann darum, wie Vue.js in diesem Kosmos entstand. Dabei wird auf die Grundkonzepte und die wichtigsten Funktionalitäten des progressiven Frameworks eingegangen. Abschließend wird erörtert, ob der Einsatz von Vue.js eine zukunftssichere Entscheidung ist.
Historischer Rückblick
Zunächst blicken wir auf die letzten beiden Jahrzehnte der Web-Entwicklung zurück. Es ist noch nicht allzu lange her, dass Webseiten reine Dokumente waren, basierend auf HTML-Dateien der HTML 4.01 Spezifikation. Das Erscheinungsbild des Markups der HTML-Datei konnte mit Einsatz von CSS2 gestaltet werden. Mit einem geringen Anteil an logischer Funktionalität, hinzugefügt durch JavaScript-Dateien, wurden beispielsweise Änderungen des Stylings nach bestimmten Benutzerinteraktionen oder die Überprüfung von Formularen im Webbrowser ermöglicht.
Mit AJAX folgte 2005 ein neuer Ansatz für Webapplikationen, dass das asynchrone Laden von JavaScript und XML ermöglichte. Ein Jahr später erfolgte die Veröffentlichung von jQuery. Erst am 28. Oktober 2014 wurde die HTML5 Spezifikation veröffentlicht. Zu diesem Zeitpunkt wurde jQuery laut builtwith auf 63 Prozent der „Top 1 Million Websites“ eingesetzt. Ab diesem Zeitpunkt scheint sich das Web rasend schnell zu entwickeln. Die in Computern eingesetzte Hardware wurde besser, Smartphones gewannen an Beliebtheit. Es wurde durch die neuen Webtechnologien leichter, Funktionalitäten und Logik vom Server in den Client zu überführen. Terminologien wie „Mobile First“ und „Offline First“ gewannen in vielen Unternehmen eine hohe Bedeutung. Das führte zu der Entwicklung von mehreren Frameworks und Mikro Bibliotheken.
Mit komplexeren Anforderungen mussten Formate geschaffen werden, um die neu geschaffenen Aufgabengebiete eines Frontend-Entwicklers abzubilden. Letztendlich kristallisierten sich Angular und React als die beiden aktuell meist verwendeten Frameworks bzw. Bibliotheken heraus. Grundsätzlich unterscheiden sich die beiden darin, dass Angular ein komplettes Web Applications Framework ist, während React zu der Kategorie der Mikro Bibliotheken gehört.
Die Entstehung von Vue.js
Doch wie entstand nun Vue.js neben den bestehenden großen und kleinen Frameworks?
Erfunden wurde das Framework von Evan You, einem ehemaligen Mitarbeiter von Google. Dort arbeitete er mit seinem Team an Ideen und Konzepten für noch nicht veröffentlichte Software-Produkte. Dafür bauten sie viele Prototypen, die sie mit AngularJS entwickelten.
Evan fielen dabei Nachteile des Frameworks für ihre spezifische Tätigkeit auf. Ein AngularJS Projekt ist mächtig und bietet viel Funktionalität, die entsprechende Komplexität mit sich bringt. Die Stärken von AngularJS liegen bei komplexen Webapplikationen, deren Entwicklung und Wartung durch die Unterstützung des schwergewichtigen Frameworks erleichtert wird. Das stand im Widerspruch zu der Problematik von der Entwicklung vieler kleiner Projekte, bei denen Wartbarkeit und Weiterentwicklung nicht an erster Stelle standen. Dieser Projekttyp beschreibt leichtgewichtige Applikationen, die von keiner langen Lebensdauer sind.
Aus diesen Gründen begann Evan You ein Nebenprojekt, um sich ein Framework zu schaffen, dass bestens für kleine Prototypen geeignet war. Inspiriert wurde es dementsprechend durch AngularJS, und somit kann man Parallelen, wie beispielsweise das Konzept der “deklarativen Templates”, zwischen den Frameworks feststellen. Während AngularJS auf ein “Two-way Data-binding” setzt, wird bei Vue.js ein “One-way Data-flow” zwischen Komponenten ermöglicht, um die Komplexität zu verringern. Ebenfalls umging er das Konzept der “Dependency Injection” und löste die Problematik des “Dirty Checking” anders als es bei AngularJS gehandhabt wird. Somit war die erste Version von Vue.js nicht eine reduzierte Version von AngularJS, sondern verfolgte auch ab frühestem Stadium bereits andere Prinzipien.
Mit der Zeit gewann Evans Projekt Beliebtheit auf GitHub. Die Community fing an, mitzuhelfen und stellte Anfragen für bestimmte Features. So entstanden nach und nach First-Party Plugins wie der Router oder State Management. Somit wuchs Evans Nebenprojekt langsam, und es bildete sich ein Core Team an Entwicklern. Eine der größten Stärken von Vue.js ist, dass diese Zusatzfeatures nicht automatisch im Kern von Vue.js mitgeliefert werden, sondern je nach Bedarf hinzugenommen werden konnten — es ist damit ein “progressives” Framework. Somit wurde die Entwicklung von kleinen Prototypen immer noch gewährleistet, während auch größere komplexere Applikationen ermöglicht wurden. Vue.js passt sich dementsprechend an die Projektkomplexität an.
Nach sieben Monaten Entwicklungszeit widmete sich das Kernteam sechs Monate lang der Dokumentation. Diese umfangreiche und einfach zu verstehende Dokumentation, so wie der progressive Grundgedanke des Frameworks sind die Hauptgründe der großen Beliebtheit von Vue.js in der Community (wie Evan You in dem Views on Vue Podcast erzählt). Die erste offizielle Version, Vue 1.0.0 mit dem Codenamen Evangelion, wohl ein Wortspiel, wurde letztendlich im Februar 2014 auf GitHub veröffentlicht. Die folgende Grafik zeigt den steilen Anstieg an Downloads ab diesem Zeitpunkt.
Die Aussprache von Vue.js sorgte anfangs für Verwirrungen. Der Name des progressiven Frameworks ist die französische Übersetzung des englischen Wortes “view”. Ausgesprochen wird es aber englisch.
Vue.js — das progressive Framework
Wie sieht Vue.js nun genau aus? Neben der Eigenschaft der Progressivität durch die sich anpassende Komplexität der Codebase an das Projekt, sind die wichtigsten Bestandteile die Verwendung eines Virtual DOM und das Deklaratives Rendering bei Single File Components. Hierbei vermischen sich die Eigenschaften der großen Frameworks. Einen Virtual DOM findet man ebenfalls bei React, das Deklarative Templates bei Angular.
Im Folgenden wird genauer auf folgende Punkte eingegangen:
- Virtual DOM
- Single File Components
- Template Sektion
- Script Sektion
- Deklaratives Rendering
- Style Sektion
- Wiederverwendbarkeit
- Aufteilen in mehrere Dateien
Virtual DOM
Als einen virtuellen DOM kann man sich ein abstrakte Duplikat des eigentlichen DOMs vorstellen. Die Größe der Kopie ist um einiges geringer, da es nur die Bestandteile enthält, die sich tatsächlich auch verändert können. Sobald DOM-Updates erfolgen sollen, werden diese zuerst einzeln im Virtual DOM vorgenommen. Ein intelligenter Algorithmus vergleicht im Anschluss die Unterschiede in einem Zug im tatsächlich gerendertem DOM.
Single File Components
Vue.js setzt auf Single File Components. Durch dynamisches Bundling ist es möglich, HTML, JavaScript und CSS in getrennte Dateien abzulegen — dennoch gilt hier der Grundsatz einer abgeschlossenen Komponente. In der Regel werden alle drei Bestandteile in eine Datei geschrieben. Kleine Komponenten haben den Vorteil, testbar, wartbar und leicht erweiterbar zu sein. Diese Komponenten folgen daher dem Prinzip des Separation of Concerns. Dieses Prinzip bedeutet, dass man Zuständigkeiten strikt voneinander trennt. Eine einzelne Komponente erfüllt genau eine Aufgabe, nicht mehr und nicht weniger. Dadurch kann gewährleistet werden, dass die Komponente universell einsetzbar ist.
Der Code oben zeigt die drei Abschnitte einer Single File Component:
- Das Markup als Template in HTML
- Die Logik als Skript in JavaScript
- Der Style in CSS
Diese Single File Components lassen sich nun baumartig miteinander verbinden. Manch einer beschreibt das gerne als Legobausteine. Der übliche Kommunikationsweg zwischen Komponenten ist, dass die Elternkomponente props an ihre Kinder überreicht und per emit über Events benachrichtigt werden kann. So wird eine Applikation üblicherweise aufgebaut:
Template
Vue.js lässt einem generell viel Gestaltungsfreiraum. So spielt es aus technischer Sicht keine Rolle, ob man das Template in HTML, JSX oder auch Pug schreibt. Mit den jeweiligen Einstellungen in der Konfigurationsdatei lassen sich die Dialekte transformieren.
Die einfachste Variante, um ein Databinding mit dem Script herzustellen, ist die “Mustache” Syntax, die man bereits von Handlebars kennt:
<p>{{ greeting }} World!</p>
In den Platzhalter wird automatisch von Vue.js der Wert hello des Data-Attributs eingesetzt. Ändert man im Script den Wert von greeting, passt sich auch das Template automatisch an. Dafür muss der Entwickler nicht mehr den Selektor anfragen und den Wert spezifisch ändern.
Außerdem stehen weitere Schlüsselwörter, Funktionen zur Verfügung, unter anderem:
- v-if / v-else
- v-show
- v-once
- v-html
- v-text
Auch Eventhandler können direkt an das HTML Tag hinzugefügt werden, zum Beispiel:
- @click
- @click.prevent für automatisches Aufrufen von event.preventDefault()
- @click.stop für automatisches Aufrufen von event.stopPropagation()
Um dynamische Werte an das Tag zu binden, benutzt man ein Shorthand mit einem Doppelpunkt als Prefix, zum Beispiel:
- v-bind:href
- v-bind:src
- :href (mit Shorthand)
- :src (mit Shorthand)
Wäre greeting zum Beispiel der Quellenverweis auf ein Bild, so könnte man folgendes schreiben:
<img :src=”greeting” alt=”” title=””>
Die Möglichkeiten im Template werden hier genauer beschrieben.
Script
Eine Vue Komponente kann global oder lokal registriert werden. Das ist abhängig von der Architektur des Projektes. Generell können dem Script unter anderem folgende Optionen übergeben werden:
- Datengebunden: Hierunter fallen reaktive Datenattribute und Methoden, die mit den Schlüsselwörtern data, props, propsData, computed, methods und watch angewendet werden können.
- DOM-gebunden: Je nachdem, wie man das HTML an die Komponente binden möchte, kann man Optionen für el, template und render verwenden.
- Lifecycle Hooks: Neben den computed values und methods gibt es weitere Methoden, die von Vue.js zu bestimmten Zeitpunkten ausgeführt werden, wie zum Beispiel created, mounted, updated oder destroyed.
Auch das Hinzufügen eines Namens, Referenzen zu Kindkomponenten und Mixins lassen sich im Script unterbringen.
INFO: Auch für Freunde von TypeScript gibt es Loader. Der Kern der nächsten Vue.js Version, Vue 3, ist sogar komplett in TypeScript implementiert worden.
Deklaratives Rendering
In dem reduzierten Beispiel der hello.vue (siehe obere Grafik der Single File Component) ist das Datenattribut mit dem Key greeting hinterlegt. Es konnte mit Hilfe der Mustache Syntax an das Template gebunden werden. Dadurch werden die Daten und der DOM verbinden, man bezeichnet diese Verbindung als reaktiv. Doch was ist nun Deklaratives Rendering?
Man betrachte hierfür ein weiteres Beispiel:
Hier wird nun die Mustache Syntax und das Binden von Dateiattributen per v-bind vermischt. Im Prinzip funktionieren sie identisch. Ändert sich der Wert von myHomepage oder message, wird das Template automatisch angepasst. Das Ganze funktioniert ebenfalls in die andere Richtung. Bindet man ein Datenmodell an ein Input Feld, so wird der Wert des Modells automatisch angepasst, sobald der Nutzer ihn verändert.
Style
Auch der Style muss nicht in purem CSS3 geschrieben werden. Der Einsatz von SCSS oder SASS ist über das Sprachattribut setzbar. Zusätzlich kann das Schlüsselwort scoped gesetzt werden. Der Vue Loader kann dieses Attribut dazu nutzen, um die dort gesetzten Styles nur auf spezifisch bei der Komponente einzusetzen. PostCSS wird beim Transformieren einen Hash an die Selektoren setzen. So wird in der oben gezeigten Grafik aus dem p zum Beispiel ein p[data-v-f3f3eg9]. Das Attribut scoped verhindert zwar nicht das Setzen von globalen Styles für alle Paragraphen, aber sorgt dafür, dass nicht andere Paragraphen anderer Komponenten ebenfalls zentriert in der Größe von 2em geschrieben werden.
Wiederverwendbarkeit
Um Komponenten dynamisch und wiederverwendbar zu gestalten, gibt es die Möglichkeit, Mixins und Slots einzusetzen. Mixins werden dabei in der Form von einer Vue Komponente geschrieben und tatsächliche Komponenten können diese Mixins integrieren, um den Funktionsumfang ebenfalls zu nutzen. Auf der anderen Seite sind Slots etwas wie Platzhalter. So kann die Elternkomponente einen beliebigen Inhalt in den Slot einer Kindkomponente einfügen, ohne dass die Kindkomponete wissen muss, was dieser Inhalt darstellt.
Aufteilung in mehreren Dateien
In Vue.js ist man nicht dazu gezwungen, eine Single File Component auch immer in eine einzelne Datei zu schreiben, auch wenn das dem ursprünglichen Namen widerspricht. Es ist möglich, das HTML, CSS und JavaScript in mehrere Dateien abzulegen. Dadurch könnten CSS und JavaScript ausgelagert und in die Datei des Templates importiert werden, wie hier im Beispiel aus dem offiziellen Guide zu sehen:
<!-- my-component.vue -->
<template>
<div>This will be pre-compiled</div>
</template>
<script src="./my-component.js"></script>
<style src="./my-component.css"></style>
Beispiel Setup mit Vue CLI 3
Mit dem theoretischen Wissen über die historische Entwicklung und Eigenschaften sowie Vorteile von Vue.js gerüstet, lässt sich nun herausfinden, ob die Benutzung des Frameworks wirklich so einfach ist oder ob es doch nur ein Hype ist. Ähnlich wie es für React das Tool “Create React App” und für Angular die “Angular CLI” gibt, lässt sich auch ein neues Vue.js Projekt über das Command Line Interface sehr einfach konfigurieren.
Die “Vue CLI” gibt es aktuell in der dritten Version, die einige Verbesserungen zur zweiten Version aufweist. Es bietet jedem Entwickler unter anderem out-of-the-box Support für:
- Vorkonfiguriertes Webpack 4 Setup mit Hot Module Replacement, Code Splitting, Treeshaking und vielem mehr
- ES2017 Transpiler durch Babel 7 und preset-env
- PostCSS und alle großen Präprozessoren
- Generiertes HTML für das Basis Setup
Darüber hinaus gibt es weitere optionale Integrationen wie TypeScript, PWA, Vue Addons wie Router und Store, Linter und Testing.
Damit man Vue CLI nutzen kann, sollten zusätzlich noch node und npm auf dem Computer installiert sein. Um dann loszulegen, gibt man
$ vue create project-name
in die Kommandozeile des Terminals ein. Als nächstes entscheidet man sich für die Features, die man voraussichtlich benutzen möchte.
Setup eines neuen Vue.js Projekts mit Vue CLI 3
Hier zeigt sich der große Vorteil des progressiven Frameworks: man pickt sich genau das heraus, was man braucht. Nicht mehr und nicht weniger. Stellt sich zu einem späteren Zeitpunkt heraus, dass man doch auch einen Router oder Vuex braucht, fügt man es ganz einfach über
$ vue add [PLUGINNAME]
hinzu. Nach kürzester Zeit steht einem danndas Grundgerüst eines neuen Projekts zur Verfügung. Tiefergehende Informationen zu dem Funktionsumfang von der Vue CLI finden sich hier. Als Alternative zum Command Line Interface bietet Vue CLI 3 auch eine grafische Weboberfläche an. Dazu führt man den Befehl vue ui aus, welches ein User Interface generiert, das sich automatisch in einem Browser öffnet.
Das User Interface zeigt einem (üblicherweise unter http://localhost:8000) eine Projektverwaltung über alle Vue Projekte von dem Ordner, von dem man die Oberfläche aus gestartet hat, an. Um ein neues Projekt zu erstellen, geht man auf den Reiter mit dem Label “Neu”. Hier hat man die gleichen Möglichkeiten, sich ein Projekt zusammenzustellen, wie auch beim Command Line Interface. Man setzt Details über das Projekt fest, wie Name, Paket- und Versionsverwaltung, bestimmt den Funktionsumfang und konfiguriert die Einstellungen für einen Linting.
Konfiguration des Funktionsumfangs eines Vue.js Projektes mit der grafischen Oberfläche
Wie bei dem Weg über das Terminal, ist es möglich, auch zu einem späteren Zeitpunkt den Funktionsumfang zu ändern, in dem man das User Interface erneut aufruft und Anpassungen vornimmt. Die Auswahl der Funktionen lässt sich als eine Voreinstellung speichern, sollte man für mehrere Projekte immer wieder das gleiche Setup benötigen. Nachdem man die Konfiguration eines neuen Projektes abgeschlossen hat, generiert die Vue CLI automatisiert das Setup mit vorgeschriebenen Templates. Üblicherweise wird in der package.json der Befehl npm run serve angegeben sein, um das Projekt zu starten. Lässt man dieses Skript laufen, ohne Änderungen an den automatisch generierten Dateien vorgenommen zu haben, gelangt man auf folgende Seite:
Diese Startseite zeigt einem nochmals an, mit welcher Konfiguration und mit welchen Plugins das Projekt aufgesetzt wurde. Ab nun steht einem nichts mehr im Wege, mit der eigentlichen Entwicklung zu beginnen.
Abschließende Gedanken
In diesem Artikel wurde darauf eingegangen, wie es zu der sog. “Frontend Fatigue” kommen konnte, ein universelles Thema der Webentwicklung, das auch beschreibt, wie es zu Vue.js kam. Das progressive Framework hat mittlerweile einen festen Fuß gefasst und wird bereits bei vielen Firmen eingesetzt. Die Vorteile von Vue.js sind zum einen der kleine Kern, der dadurch auch zu einer geringen Dateigröße an ausgeliefertem JavaScript führt, zusammen mit der Erweiterbarkeit des Funktionsumfangs, der sich dementsprechend an die Projektkomplexität anpasst. Zum anderen ist die leichte Erlernbarkeit ein großer Pluspunkt des Frameworks. Das bedeutet nicht, dass Programmieren per se leicht wäre. Es geht immer noch um das Einsetzen von Design Patterns, Implementieren von Algorithmen und dem Umsetzen von Stylings. Vue.js ist von Entwicklern für Entwickler geschrieben. Das merkt man schnell, sobald man es einfach einmal ausprobiert.