Kurzeinführung in das progressive JavaScript-Framework

Vue.js in a Nutshell – Einführung in das progressive JavaScript-Framework
Keine Kommentare

Schon wieder ein JavaScript-Framework? Ja, ist denn heut’ schon Dienstag? Keine Bange, Vue.js ist anders. Die schlanke Bibliothek bedient alle Nischen, die bislang von Frameworkentwicklern außer Acht gelassen wurden, und dank der inkrementell einsetzbaren Zusatzbibliotheken aus dem Umfeld auch alle anderen gängigen Fälle gleich mit.

Schon die Entstehungsgeschichte von Vue.js ist anders. Hinter dem neuen Stern am JavaScript-Himmel steckt diesmal kein Großkonzern oder Social-Media-Haus, sondern eine Einzelperson. Evan You hat als Creative Coder zwar mal bei den Google Creative Labs gearbeitet, sein JavaScript-Framework entstand aber aus eigenem Interesse. Nach der Veröffentlichung 2014 nahm die Beliebtheit der Bibliothek Fahrt auf. Das Release der Version 2 im September 2016 hat Vue.js dann auch unter großen Firmen etabliert. Mittlerweile kann Evan You durch Sponsoren, OpenCollective und Patreon-Spenden seit über zwei Jahren in Vollzeit an Vue.js arbeiten, was man dem Fortschritt und der Stabilität auch anmerkt.

Doch was kann Vue.js, was andere nicht können? Halten wir das für den Rest des Artikels an zwei Begriffen fest: Progressivität und inkrementelle Einsetzbarkeit. Vue.js kann man sowohl für Teile einer bestehenden Applikation oder Webseite einsetzen, aber auch als vollständigen Ersatz für jQuery-basierte JavaScript-Anreicherungen in interaktiven Widgets. Schrittweise kann man nun wiederverwendbare Komponenten, moderne JavaScript-Syntax und Präprozessoren dazuschalten. Will man von ein paar Widgets zu einer vollständigen Applikation, kann das umfangreiche Ökosystem der Bibliothek mit Authentifizierung, Routing und State Management aufwarten. Ganz wie die Großen!

Hello, Vue!

Darüber hinaus braucht man kein Fachdiplom, um mit Vue.js zu starten. Es reicht eine 20 Kb große JavaScript-Datei (minifiziert und mit GZIP ausgeliefert) und ein wenig eigenes JavaScript. Keine langwierigen Build-Prozesse, keine Commandline-Tools, keine Syntaxerweiterungen wie TypeScript oder JSX. Das heißt nicht, dass diese Dinge nicht alle möglich und vorhanden sind. Es gibt auch Fälle, in denen es durchaus sinnvoll ist, ein komplexeres Set-up einzusetzen. Doch für den Beginn reichen ein wenig Markup, ein bisschen CSS und erstaunlich wenig JavaScript. In den folgenden Listings sehen Sie alles, was man für ein einfaches „Hello World“ mit Vue.js benötigt. Unsere HTML-Datei reichern wir mit ein wenig Markup an.

...
    <div id="app">
      <h1> {{ msg }} </h1>
    </div>
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
    ...

Wichtig ist die eindeutige ID app unseres Elternelements. Dieses Element ist der Einstiegspunkt für unsere Applikation. Von da an wird alles von Vue.js übernommen, und wir erkennen auch gleich die allseits bekannte Templatesyntax mit den geschwungenen Klammern wieder. Hier erwarten wir uns von Vue.js Daten mit dem Namen msg. Nun, wenn man das schon erwartet, wollen wir das auch kurz zur Schau stellen:

new Vue({
  data: {
    msg: 'Hello World! '
  },
  el: '#app'
})

Dies ist das gesamte JavaScript, das wir benötigen. Wir legen eine neue Vue.js-Instanz an und hängen sie an das Element #app. Elemente selektiert man mit CSS-Selektoren, das kennen wir von jQuery. Auch das data-Objekt ist selbsterklärend. Die Property msg hier ist analog zu dem, was wir in unserem Template haben. Einfach? Ja! Langweilig? Das auch. Also weiter zu etwas Ansprechenderem: Einem Counter Widget.

Interaktion und Reaktivität

In der heutigen Zeit scheint es, dass Counter Widgets der einst beliebten To-do-Liste in Sachen Demoapplikationen den Rang abgelaufen haben. Der Grund liegt auf der Hand: Man kann unglaublich schön reaktive Datenströme damit erklären. Sehen wir uns das einmal bei Vue.js an. Unser Ziel: Ein kleiner Zähler, der beim Klick auf den PLUS-Button die aktuelle Anzahl erhöht, und beim MINUS-Button genau das Gegenteil bewirkt.

Das data-Objekt bei Vue.js hat eine ganz besondere Eigenschaft. Properties in diesem Objekt werden nicht nur in Templates zugänglich gemacht, sie werden beim Erstellen der Vue.js-Instanz auch reaktiv. Bei Änderung einer Property wird ein Ereignis losgetreten und sämtlichen Prozessen, die von diesem Ereignis wissen sollen, wird der neue Wert mitgeteilt. Wie zum Beispiel Ausgaben im Template. Man merkt ein wenig Vue.js-Magie bereits, wenn man die Property manipulieren möchte. Analog zum data-Objekt hat die Vue.js-Instanz nämlich auch ein methods-Objekt, wie wir in Listing 1 sehen. In diesem Objekt werden Methoden gespeichert, die später bei Klick oder anderen Invokationsmöglichkeiten aufgerufen werden. Will man aber auf das data-Objekt zugreifen, reicht ein einfacher Zugriff über this, wie in this.count. Nun ist this in der JavaScript-Welt sowieso schon berüchtigt mehrdeutig. Vue.js legt aber noch eins drauf: Egal ob über Inline-Funktionen in Templates (die gibt es nämlich auch), gewöhnlichen JavaScript-Funktionen im methods-Objekt oder über Arrow Functions im Methods-Objekt, this ist jedes Mal die Vue.js-Instanz. Und in dieser Instanz sind nun Eigenschaften verfügbar, die wir ganz woanders definiert haben. Diese Properties wurden erzeugt und besitzen die Property-Deskriptoren get und set. Beim Zugriff auf diese Property übernimmt also Vue.js die Kontrolle über den weiteren Verlauf. So kann man einfach Daten ändern und das Ergebnis im Template wieder ausgeben.

Um allerdings Funktionen aus dem methods-Objekt aufzurufen, brauchen wir Nutzerinput. Mit ein wenig Extra-Markup in unserem Template können wir Methoden auf Ereignisse binden. Ein @click=“up“ bei einem button-Element zum Beispiel entspricht einem addEventListener für ein click-Event. Nur dass Vue.js uns hier die Arbeit abnimmt und auch gleich noch erkennt, welche Methode wir in unserem methods-Objekt meinen. Der finale Code steht in Listing 1 und ist entsprechend überschaubar.

      <div id="app">
      <h1> {{ count }} </h1>
      <button @click="up">+</button>
      <button @click="down">-</button>
    </div>
....<script src="https://cdn.jsdelivr.net/npm/vue"></script>
    <script>
    new Vue({
  data: {
    count: 0
  },
  methods: {
    up() {
      this.count = this.count + 1;
    },
    down() {
      this.count = this.count – 1;
    }
  },
  el: '#app'
})
</script>

Mit dem Anhängen von Methoden an Ereignisse sind wir auch schon beim nächsten Vue.js-Konzept: Direktiven.

Direktiven

Wenn wir mit @click eine Methode an ein Ereignis binden, nutzen wir schon die Kurzschreibweise für etwas, das man bei Vue.js Direktiven nennt. @click in der längeren Variante ist v-on:click und dürfte erfahrenen Angular.js-1.x-Veteranen sehr bekannt vorkommen. Im Vergleich zu Angular.js allerdings kommen Direktiven nur in Attributen vor. Direktiven in Tag-Form nennt Vue.js wie jedes andere moderne JavaScript-Framework Komponenten. Diese Direktiven erlauben nun, JavaScript-Ausdrücke direkt in unsere Templates zu bringen und damit die Erzeugung von weiteren DOM-Elementen zu beeinflussen. Die bekanntesten und verbreitetsten sind die folgenden:

  • v-if hängt die Erzeugung der DOM-Elemente an die positive Auswertung einer Bedingung
  • v-for wiederholt die Erzeugung der DOM-Elemente für mehrere Einträge in einem Array
  • v-on bindet Methoden an Ereignisse, wie z. B. click, keydown, submit und ähnliches
  • v-bind bindet die Inhalte diverser Attribute an ein Feld der Vue.js-Instanz; wir kennen das als 2-Way-Data-Binding aus anderen Frameworks

Es gibt noch eine Reihe mehr, und man kann bei Bedarf auch noch weitere hinzufügen. Für den Standardfall ist man aber mit den hier erwähnten Direktiven gut bedient. Sehen wir uns ein paar davon in Aktion an. Wir wollen unser Counter Widget von vorhin in etwas Sinnvolleres verwandeln: eine Lagerbestandsverwaltung, deren Produkte einen Namen (name) und eine Anzahl (quantity) haben. Diese werden in einem Array im data-Objekt gespeichert. Wir wollen eine ungeordnete Liste für jedes Element in diesem Array anzeigen. Um über dieses Array zu iterieren, verwenden wir die v-for-Direktive, die ein Format im Stil von v-for=“product in products“ erlaubt. Products ist der tatsächliche Name des Arrays im data-Objekt, Product ein Alias für das aktuell ausgewählte Element. Mit diesem Alias ist das Element nun in unseren Templates verfügbar.

Wir nutzen das gleich, um mit dem bekannten v-on:click bzw. @click die Menge des Eintrags zu erhöhen. Ein einfaches @click=“product.quantity +=1″ erhöht den Eintrag. Vue.js kümmert sich darum, dass die Daten in der Instanz aktualisiert werden und der reaktive Datenstrom angetriggert wird.

Zu guter Letzt geben wir noch eine Warnung. Wenn für Elemente meiner Produktliste weniger als fünf Stück verfügbar sind, fordern wir den Nutzer auf, doch vielleicht den Lagerbestand zu erhöhen. Eine Nachricht in einem span, die im Falle von v-if=“product.quantity < 5″ angezeigt wird, hilft uns dabei. Listing 2 zeigt den finalen Code.

<div id="app">
  <ul>
    <li v-for="product in products">
      {{product.name}}: {{product.quantity}} 
       <button @click="product.quantity += 1">+</button>
       <button @click="product.quantity -= 1">-</button>
       <span v-if=”product.quantity < 5”>{{ product.name }} werden knapp!</span>
    </li>
  </ul>
</div>
    <script src="https://cdn.jsdelivr.net/npm/vue"></script>
    <script>  
    new Vue({
  data: {
    products: [{
      name: 'Schuhe',
      quantity: 1
    }, {
      name: 'Socken',
      quantity: 10
    }, {
      name: 'Shirts',
      quantity: 12
    }],  
  },
  el: ‘#app’
})
</script>

Wie wir sehen, ist der JavaScript-Code nicht viel umfangreicher geworden als im vorherigen Beispiel. Die Templates sind sehr mächtig, und mit der Auswertung von JavaScript-Ausdrücken im Templatecode selbst spart man sich einiges an Funktions-Boilerplate.

Zugegeben, wir sind noch ein wenig von einer vollwertigen Single-Page-Applikation entfernt, diese knappen Beispiele erlauben uns allerdings gleich, auf ein paar wichtige Kernkonzepte von Vue.js zu blicken:

  • Templates sind unglaublich mächtig. Durch Direktiven und die Auswertung von JavaScript-Ausdrücken direkt lassen sich ganze Widgets im Templatecode erzeugen. Man muss nur die Datenstruktur in der Vue.js-Instanz definieren.
  • Der reaktive Datenstrom ist allgegenwärtig. Die Änderung eines Werts irgendwo in der Applikation wirkt sich direkt auf die Anzeige des Werts im DOM aus.

Beim letzten Aufzählungspunkt, dem reaktiven Datenstrom, haben wir allerdings erst an der Oberfläche gekratzt. Mit watched und computed properties sehen wir, wie wirkungsvoll dieser Strom sein kann.

„watched“ und „computed properties“

Die Anzeige von Daten ist bislang relativ simpel gehalten: Wir ändern einen Eintrag in unserem Datenobjekt. Diese Aktualisierung wird in den Templates angezeigt. So weit, so gut. In den meisten Fällen brauchen wir jedoch auch Anzeigen, die nicht ganz zu unserem Datenmodell passen. Nehmen wir die Lagerbestandsverwaltung von vorhin wieder als Beispiel. Es wäre doch schön, wenn wir nicht nur die Anzahl der Produkte für jeden einzelnen Eintrag sehen, sondern auch die Summe aller Artikel bei uns im Lager. Für derartige Dinge hat Vue.js sogenannte Computed Properties, also errechnete Eigenschaften. Wer früher mit Ember.js herumgewerkt hat, kennt die grundlegende Herangehensweise.

Wie schon bei Methoden und Daten, braucht Vue.js ein weiteres Feld in der Instanz: computed. Dieses Feld nimmt nun eine Reihe an Funktionen ein, und jede dieser Funktionen benötigt einen Rückgabewert. Ist er vorhanden, ist nun in der Vue.js-Instanz (und somit auch in den Templates) eine eigene Property vorhanden, die wir ausgeben können – ganz so, als würde dieses Feld in unserem data-Objekt stehen. Das Besondere dabei ist, dass wir in dieser Funktion auf Werte unseres data-Objekts zugreifen können und die Computed Property sich mit Änderungen des Originals aktualisiert.

Wenn wir für unsere Lagerbestandsverwaltung also eine Gesamtanzeige haben wollen, brauchen wir im computed-Feld eine Funktion namens total, die alle bestehenden Produktbestände addiert. Eine Änderung bei einem Produktbestand aktualisiert auch total. total, eigentlich eine Funktion, ist nun auch ein Feld, das wir in unseren Templates verwenden können. Listing 3 zeigt das Beispiel.

Doch damit nicht genug. Mit Vue.js können wir noch einen Schritt weiter gehen. Angenommen, wir wollen total rot anzeigen, sobald es einen definierten Schwellenwert unterschritten hat. Dazu müssen wir total beobachten und je nach Wertänderung eine Klasse in einem DOM-Element setzen. Mit Watched Properties stellt uns Vue.js genau diese Funktionalität zur Verfügung.

Analog zu den restlichen Eigenschaften bekommen wir ein Feld watch in der Vue.js-Instanz. Dieses Feld nimmt nun auch Funktionen an. Diese müssen im Namen allerdings einem Feld im data-Objekt oder einer Computed Property entsprechen. Der Grund: Sowie sich ein Feld mit diesem Namen ändert, triggert es unsere Watched Property und führt eine Funktion aus. In dieser können wir wiederum Werte aus dem data-Objekt ändern.

Für unser Beispiel erstellen wir also eine Property im data-Objekt namens totalClass. Dieses Feld ist ein Klassenname, der entweder normal lautet oder red. Bei red sollten wir dringend unser Lager aufstocken. Mit v-bind:class oder der Kurzschreibweise :class sorgen wir dafür, dass sich das class-Attribut beim DOM-Knoten ändert, wenn sich etwas im Feld totalClass ändert.

Nun legen wir einen Watcher für unsere Total Computed Property an. Diese Methode übergibt einen Parameter, den aktuellen Wert. Ist dieser Wert kleiner als zehn, färben wir die totalClass rot. Listing 3 zeigt, wie das funktioniert.

<div id="app">
  <ul>
    <li v-for="product in products">
      {{product.name}}: {{product.quantity}} 
        <button @click="product.quantity += 1">+</button>
        <button @click="product.quantity -= 1">-</button>
        <span v-if="product.quantity < 5">{{ product.name }} werden knapp!</span>
    </li>
  </ul>
  <p>
    <strong>Total quantity:</strong> <span :class="totalClass">{{ total }}</span>
  </p>
</div>
<style> 
red {
  color: red;
}
</style>
    <script src="https://cdn.jsdelivr.net/npm/vue"></script>
    <script>  
    new Vue({
  data: {
    products: [{
      name: 'Schuhe',  quantity: 1
    }, {
      name: 'Socken', quantity: 10
    }, {
      name: 'Shirts', quantity: 12
    }],
    totalClass: 'normal'  
  },
  computed: {
    total() {
      return this.products.reduce((acc, el) => {
      return acc + el.quantity
      }, 0)
    }
  },
  watch: {
    total(val) {
      if(val < 10) {
        this.totalClass = 'red';
      } else {
        this.totalClass = 'normal';
      }
    }
  },
  el: ‘#app’
})
</script>

Wir sehen, dass der Datenstrom ganz schön komplex sein kann. Eine Änderung in unseren vordefinierten Daten ändert eine errechnete Eigenschaft. Diese wiederum triggert einen Beobachter, der wiederum einen Wert in den vordefinierten Daten ändert. Wer glaubt, dass man hier ganz schnell in eine zyklische Abhängigkeit laufen kann und gar in eine Endlosschleife fällt, liegt richtig. Vue.js ist allerdings schlau genug, um das zu merken, und stoppt einfach die Ausführung. Man bemerkt das an einem Kommentar in den Entwicklertools.

Da Vue.js ziemlich gut im Auswerten von JavaScript-Ausdrücken ist, kann man als Entwickler sehr bequem arbeiten und viel Handarbeit dem Framework überlassen. Die Aktualisierung von Eigenschaften wirkt fast wie Voodoo, ist aber einleuchtend, wenn man ein klein wenig unter die Haube schaut.

Bislang gab uns Vue.js schon alles, was wir für eine kleine Applikation benötigen. Wollen wir allerdings etwas Größeres, müssen wir ein wenig filigraner arbeiten.

Komponenten

Komponenten sind ja das große Ding in SPA-Frameworks. Gerade React rühmt sich, das Zeitalter der Komponenten eingeläutet zu haben. Nun, erfahrene Softwareentwickler wissen, dass die Modularisierung diverser Softwarebausteine zu wiederverwendbaren Komponenten nicht unbedingt erst seit ein paar Jahren ziemlich en vogue ist. Aber man muss zugeben, nie war es einfacher als in der heutigen Zeit, wiederverwendbare UI-Bausteine für Webapplikationen zu stricken. Vue.js macht da keine Ausnahme.

Gerade wenn wir eine Applikation wollen, die nicht nur aus einem Widget und einem sehr einfachen Datenstrom besteht, brauchen wir eine Vielzahl an Widgets, die wir in unterschiedlichem Kontext mit unterschiedlichen Daten befüllen können. Vue.js gibt uns die Möglichkeit, die bestehende Instanz um eigene Komponenten zu erweitern. Mit Vue.extend({}) können wir den bestehenden Code einfach in ein weiteres Objekt kopieren und per Variable zugänglich machen. Diese Variable können wir mit Vue.component global registrieren oder extra pro Vue.js-Instanz. Danach ist die Komponente wie ein HTML-Element in der Applikation verfügbar. In Bezug auf Komponenten gilt es nur, ein paar Dinge zu beachten:

  • Templates definiert man nicht mehr einfach so im HTML. Man kann zwar ein template-Element verwenden und es in der Komponente laden, viel gemütlicher allerdings ist es, wenn man das template-Feld in der Komponente direkt befüllt. Dieses Feld ist übrigens auch für eine Vue.js-Instanz verfügbar, falls man sich den Weg über das HTML sparen will.
  • Es gibt kein data-Objekt mehr. Das liegt daran, dass Ausgangsdaten nur per Instanz definiert werden. Die einzelnen Komponenten haben eine data-Funktion und retournieren wiederum ein Objekt. Man merkt so, dass Komponenten nun extra instanziiert werden müssen.
  • Eine weitere Eigenschaft tritt auf: Man kann eigene Attribute definieren. Mit dem Feld props definiert man ein Array aus Strings, die nur darauf warten, mit Daten von außen befüllt zu werden. So können wir das products-Feld weiter behalten, es aber mit unterschiedlichen Produkten füllen.

In Listing 4 sehen wir, wie wir aus unserer Lagerbestandsverwaltung eine Verwaltung für mehrere Kategorien gemacht haben, der my-counter-Komponente sei Dank.

<div id="app">
   <my-counter :products="clothes"></my-counter>
   <hr>
   <my-counter :products="sweets"></my-counter>
</div>
<style> 
.red {
  color: red;
}
</style>
    <script src="https://cdn.jsdelivr.net/npm/vue"></script>
    <script>  
const Comp = Vue.extend({
  template: `<div><ul>
    <li v-for="product in products">
      {{product.name}}: {{product.quantity}} 
       <button @click="product.quantity += 1">+</button>
       <button @click="product.quantity -= 1">-</button>
       <span v-if="product.quantity < 5">Buy more {{product.name}}</span>
    </li>
  </ul>
  <p>   
    <strong>Total quantity:</strong> <span :class="styleClass">{{ total }}</span>
  </p></div>`,
  props: ['products'],
  data() {
   return {
     styleClass: 'normal'
   }
  },
  computed: {
    total() {
      return this.products.reduce((acc, el) => {
        return acc + el.quantity
      }, 0)
    }
  },
  watch: {
    total(val) {
      if(val < 10) {
        this.styleClass = 'red';
      } else {
        this.styleClass = 'normal';
      }
    }
  }
});
new Vue({
  el: "#app",
  data: {
    clothes: [
      { name: 'Shoes', quantity: 1 },
      { name: 'Socks', quantity: 10 },
      { name: 'Shirts', quantity: 12 }
    ],
    sweets: [
      { name: 'Chocolates', quantity: 10 },
      { name: 'Candy', quantity: 5 }
    ],
  },
  components: {
    'my-counter': Comp
  }
    })
    </script>

Damit nähern wir uns einer Single-Page-Applikation in großen Schritten. Diese Schritte sind es allerdings auch, die Vue.js ausmachen. Wir können Punkt für Punkt immer weiter in unserer Applikation voranschreiten. Vom einfachen Widget über ein Widget mit Abhängigkeit in der Ausgabe bis hin zur wiederverwendbaren Komponente. Alles in einem Framework, und alles nach und nach freischaltbar. Für eine vollwertige Applikation brauchen wir allerdings noch mehr. Und hier kommt nun das Vue.js-Ökosystem zum Einsatz.

Das Vue.js-Ökosystem

Das umfangreiche Ökosystem von Vue.js ist mit ein Grund, warum sich das Framework bei Entwicklern so großer Beliebtheit erfreut. Anders als bei Angular kommt das Basisframework sehr schlank und überschaubar daher und hat wenig Grundbausteine, die man eigentlich bei vollwertigen Single-Page-Applikationen erwarten würde. Diese kann man sich durch Zusatzmodule beliebig dazuschalten. Damit ist Vue.js nicht ganz unähnlich zu React, hat allerdings einen gravierenden Unterschied: Bei Vue.js kommt alles aus einer Hand, nämlich aus der Hand von Evan You und seinem Kernteam. Die wichtigsten Bausteine sind hier im Überblick:

vue-router löst das allgegenwärtige Problem von Single-Page-Applikationen: Wer nur eine HTML-Datei ausliefert, hat auch nur einen URL. Ein sauberer Router allerdings weist URLs diversen Ansichten und Status in der Applikation zu. In der Anwendung ist der Router von Vue.js entsprechend einfach. Routes werden über Komponenten definiert. Damit wird eine Komponente zur View. Den Router an Vue.js angehängt, bekommen wir Komponenten wie router-link und router-view. Ein Klick auf einen router-link ändert damit eine router-view und dazu passend auch den URL in der Adressleiste. Umgekehrt hört der Vue.js-Router auch auf Änderungen in der Adressleiste und aktualisiert nach seinem Schema die View.

Features wie dynamisches Matching oder geschachtelte Routes sind natürlich alle mit dabei. Tatsächlich verfügt der Router über eine eigene Dokumentation, die auf der Homepage von Vue.js verfügbar ist. Von einfachen Demos bis hin zu komplexen Animationen ist hier alles enthalten.

Wer React kennt, liebt Dinge wie Redux. State Management, das von einem globalen State für die gesamte Applikation ausgeht, ist eines der Dinge, die die SPA-Entwicklung in den letzten Jahren so einfach und zugänglich gemacht haben. Mit Vuex bietet Vue.js ein eigenes State Handling an. Das data-Objekt wird dabei fast obsolet, alles wird über einen globalen Store gesteuert, der über eindeutige Events wie Aktionen und Mutationen verändert werden kann. Die Ausgabe in Templates wird dann über computed properties gelöst. Das ist ein wenig komplexer als Redux in der Anwendung für einfache Beispiele, aber sehr mächtig und vor allem sehr gut auf Vue.js zugeschnitten, wenn es insgesamt etwas komplexer wird. Wie schon beim Router bekommen wir auf der Homepage von Vue.js eine sehr gute Dokumentation.

Wenn von Performance gesprochen wird, dann vor allem auch von der Zeit, die von Request-Beginn bis zur Darstellung von Daten auf dem Monitor vergeht. Je kürzer, desto eher hat der Benutzer das Gefühl, dass auch etwas passiert. Damit man diese Zeit besonders gut verkürzen kann, lohnt es sich, nicht alles im Browser zu rendern, sondern vielleicht mit dem ersten Transfer des Dokuments auch schon tatsächlich Daten anzuzeigen. Unter dem Begriff „Server Side Rendering“ ist dieses Verhalten wieder populär geworden. Vue.js bietet ein Node.js-Modul namens vue-server-renderer an. Damit ist es möglich, Vue.js-Instanzen auch ohne Browserkontext zu erzeugen und Ergebnisse als HTML über den Node.js-Server zu senden. Diese Ausgaben können in einen interaktiven Kontext übergehen, wenn man die gleiche Applikation an den Browser mitschickt. Auch hierfür gibt es eine eigene Dokumentation von Vue.js, und man wird auch fündig, wenn man sein liebstes Node.js-Server-Framework mit Vue.js verwenden will.

Damit nähern wir uns in Sachen Features schon gewaltig einer vollwertigen Single-Page-Applikation. Wir können schnell Views rendern und abhängig vom URL ändern (und umgekehrt). Ein globaler Daten-Store sorgt dafür, dass wir immer wissen, in welchem Zustand sich unsere App gerade befindet. Will man allerdings als Entwickler mit seiner Applikation skalieren, braucht man etwas mehr als ein paar JavaScript-Dateien und mühselig handgeschriebenen Code. Auch dafür hat Vue.js etwas in petto: Mit dem vue-loader-Plug-in für webpack ist es möglich, eigene .vue-Dateien zu erstellen, in denen man Templates, JavaScript-Code und Styles kombiniert in Single File Components verwaltet. ganz ähnlich zu den Webkomponenten von Polymer. Damit kann man seine Applikation beliebig strukturieren und sogar CSS nur auf Komponentenbasis schreiben. Listing 5 gibt ein Beispiel.

<template>
  <div id="hello">
    <img src="http://vuejs.org/images/logo.png">
    <h1>{{ msg }}</h1>
  </div>
</template>

<script>
export default {
  name: 'hello',
  data () {
    return {
      msg: 'Welcome to Your Vue.js App'
    }
  }
}
</script>

<style scoped>
#hello {
  font-family: 'Avenir', Helvetica, Arial, sans-serif;
  
text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}
a {
  color: #42b983;
}
</style>

Das Tolle daran ist, dass der vue-loader mit anderen webpack Loadern kombinierbar ist. So kann man mit ein paar Tastenanschlägen Dinge wie Sass, LESS, TypeScript oder Ähnliches einfach hinzuschalten. Damit bleibt man bei seinen Lieblingssprachen, hat aber die gesamte Power von Vue.js darunter. So steht einer umfangreichen SPA nichts mehr im Weg.

Fazit

Vue.js ist vielleicht nicht das innovativste Framework, macht aber zwei Dinge absolut richtig. Zum einen ist es sich selbst nicht im Weg. Man kann sehr schnell und ohne großartigen Aufwand bereits richtig schöne Widgets und Applikationen schreiben. Die Lernkurve ist niedrig, das Belohnungsgefühl enorm hoch. Einsteiger werden ihre Freude an Vue.js haben, vor allem, weil man auch ohne Build-Schritt auskommt.

Zum anderen ist es in Vue.js schwierig, etwas zu finden, was nicht geht. Will man Templates und Direktiven wie in Angular, ist man bei Vue.js richtig. Will man Vues reaktiven Datenstrom aber immer noch in im React-Umfeld gebräuchlichem JSX schreiben, kostet das nur ein paar Zeilen Konfigurationscode im Build-Prozess. Jeder Präprozessor wird unterstützt, und man hat es leicht, von jedem erlernten System auf Vue.js zu wechseln.

Vue.js skaliert zudem mit den Ansprüchen des Teams sowie dem Wissensstand des Entwicklers und wird gut von Entwicklern bzw. der Community angenommen. Zumindest so lange, bis das nächste um die Ecke biegt und alles besser und einfacher macht.

Unsere Redaktion empfiehlt:

Relevante Beiträge

Hinterlasse einen Kommentar

Hinterlasse den ersten Kommentar!

avatar
400
  Subscribe  
Benachrichtige mich zu:
X
- Gib Deinen Standort ein -
- or -