Das JavaScript-Framework Vue.js, Teil 1 Vue-Instanz und Options-API

Von Dr. Dirk Koller

Auf der Suche nach einem JavaScript-Framework stolpert man zwangsläufig über die drei Vertreter Angular, React und Vue.js. In dieser Reihe stellen wir mit Vue das jüngste und vermutlich am leichtesten zu erlernende Webframework vor.

Anbieter zum Thema

Als Teil der Options-API von Vue.js dient die data-Funktion dazu, Eigenschaften für den späteren Abruf zu hinterlegen.
Als Teil der Options-API von Vue.js dient die data-Funktion dazu, Eigenschaften für den späteren Abruf zu hinterlegen.
(Bild: https://v3.vuejs.org/)

Über Angular, React und Vue.js existieren zahlreiche Beiträge im Netz, die die Frameworks vergleichen und Vor- und Nachteile aufzeigen. Darauf verzichten wie hier, denn mit allen dreien lässt sich ohne Zweifel hervorragend arbeiten. Das belegen auch zahlreiche prominente Projekte.

Vue.js. wurde von Evan You, einem ehemaligen Google-Mitarbeiter, ins Leben gerufen und gilt als leichtgewichtig, klein und schnell. Die Core-Bibliothek ist auf das Erstellen von Views fokussiert und lässt sich leicht mit anderen Projekten kombinieren.

Die neueste Vue-Version ist 3, Version 2 ist allerdings noch weit verbreitet. Letztlich ist die Version für das Erlernen des Frameworks auch nicht ganz so entscheidend, weil die Syntax weitgehend die Gleiche ist. Vorsicht ist etwa beim Einbinden von Fremdanbieter-Bibliotheken geboten.

Die großen JavaScript-Frameworks wie Angular oder React erzeugen mit ihren Command Line Interfaces (CLI) beim Anlegen von Projekten eine ganze Menge Dateien. Das ist nützlich für das Aufsetzen eines produktionsreifen Projekts, aber nicht so gut geeignet, um ein Framework kennen zu lernen. Es ist schwierig, in dieser Menge an Dateien das Wichtige zu erkennen. Und bei Vue ist das eigentlich gar nicht viel.

In diesem ersten Beitrag starten wir deshalb ohne CLI und bauen ein „Hello World“ von Hand – Vue from Scratch, sozusagen. Dabei werden die wichtigsten Konzepte des Frameworks vorgestellt. Gerüstet mit diesem Grundlagenwissen wird dann in weiteren Beiträgen ein Projekt mit dem CLI angelegt, um auch diese Variante kennen zu lernen.

Die kleinste Vue-App

Ein guter Start ist zunächst eine leere HTML-Datei index.html. Vue lässt sich darin wie Bootstrap oder andere Frameworks über einen Link zu einem Content Delivery Network (CDN) einbinden, siehe im Code den Kommentar (1). Mit einem durch die id app gekennzeichneten div-Element (2) wird der Wirkungsbereich von Vue festgelegt. Im JavaScript-Bereich wird eine Instanz der Vue-App mit der Funktion createApp() angelegt (3). Die so erzeugte App wird schließlich in den div-Bereich gemountet (4):

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <script src="https://unpkg.com/vue@next"></script> //(1)
  </head>
  <body>
    <div id="app"> //(2)
    </div>
    <script type="text/javascript">
      const app = Vue.createApp(); //(3)
      app.mount("#app"); //(4)
    </script>
  </body>
</html>

Die Instanziierung unter Vue 2 sah noch ein wenig anders aus, sie verwendete den new-Operator.

Daten anzeigen mit Text-Interpolation

Das ist so ziemlich die kleinste denkbare Vue-App, allerdings bekommt man von Vue so noch nichts zu sehen. Deswegen erweitern wir den Code noch etwas. Beim Mounten der Anwendung wird eine Instanz der Root-Komponente erzeugt und zurückgegeben:

const vm = app.mount("#app"); // vm = Instanz der Root-Komponente

Die Variable vm steht für ViewModel und wird in Vue traditionell zum Bezeichnen von Komponenten-Instanzen benutzt. Die Root-Komponente ist ein Baustein, der als Einstiegspunkt beim Rendern dient. Zum Konfigurieren dieser Komponente lässt sich der Funktion createApp() ein Objekt mit Optionen übergeben (Options-API). Eine dieser Optionen ist die Funktion data(), in der sich Properties hinterlegen lassen – hier der String „Hello Vue“ unter dem Namen message:

const app = Vue.createApp({
  data() {
    return {
      message: 'Hello Vue',
    };
  },
});
const vm = app.mount("#app");
console.log(vm.message);

Wie die letzte Zeile erkennen lässt, hat man über die Komponenten-Instanz Zugriff auf die Eigenschaften in data(). Aber nicht nur dort. Im HTML-Code kann innerhalb des Divs mit der Id app (und nur dort!) auf message zum Beispiel mithilfe einer sogenannten Text Interpolation zugegriffen werden, sie rendert die Daten im DOM. Dazu dient die Mustache-Syntax (doppelt geschweifte Klammern):

<div id="app">
  <h1>{{message}}</h1>
</div>

Öffnet man die Datei index.html im Browser, wird dort der Text „Hello Vue“ angezeigt.

Methoden und die v-on-Direktive

data() ist nur eine von vielen Optionen, die übergeben werden können. Auch Methoden lassen sich dort, unter methods, formulieren:

const app = Vue.createApp({
  data() {
    return {
      message: 'Hello Vue',
    };
  },
  methods: {
    changeMessage() {
      this.message = 'Vue rockt!'; // Zugriff auf data mit this!
    }
  }
});

Der Aufruf der Methode erfolgt zum Beispiel durch einen Klick auf eine Schaltfläche. Dieser Button wird dazu mit einer sogenannten Direktive angebunden. Eine Direktive ist ein besonderes Präfix vor einem HTML-Attribut, das Vue dazu veranlasst, mit dem DOM zu interagieren. In unserem Fall ist das Präfix v-on, es lauscht auf Events, hier click-Ereignisse, und triggert die in der Instanz angegebene Methode:

<div id="app">
  <h1>{{message}}</h1>
  <button v-on:click="changeMessage()">Klick</button>
</div>

Ein Klick auf den Button ändert message auf den neuen Wert. Änderungen an den Daten werden sofort auf der Seite aktualisiert, die Daten und das DOM sind durch Vue miteinander verbunden.

Dateneingabe und v-model

Noch deutlicher wird diese Verbindung bei der Eingabe von Daten. Ein Textfeld lässt sich mit der Direktive v-model an das Datenmodell anbinden. In der Vue-Welt nennt sich das Two Way Data Binding:

<div id="app">
  <h1>{{message}}</h1>
  <input v-model="message" />
  <button v-on:click="changeMessage()">Klick</button>
</div>

Eingaben im Textfeld werden nun direkt in message geschrieben und der Inhalt von message wiederum durch die Text-Interpolation ausgegeben. Eingabe und Ausgabe werden also bei jedem Tastendruck synchronisiert.

Der Lebenszyklus der Vue-Instanz

Beim Erzeugen der Vue-Instanz werden verschiedene Schritte durchlaufen. Die Vue-Instanz wird zunächst initialisiert, Daten und Events werden verfügbar gemacht. Anschließend werden die HTML-Template-Strings in sogenannte render()-Funktionen umgewandelt, eine virtuelle Kopie des DOMs angelegt und in das angegebene Mount-Element gemounted.

Danach überwacht Vue mit Hilfe von Observern das Datenmodel. Bei Änderungen an den Daten wird das virtuelle DOM geändert und erneut in das echte DOM geschrieben. Für jeden dieser Schritte im Lebenszyklus gibt es Hook-Methoden, die sich mit eigenem Code ergänzen lassen. Die Wichtigsten sind:

  • created()
    mounted()
    updated()

Eine Auflistung aller Methoden findet man in der Vue-Doku.

Einbinden lassen sich die Hooks ebenfalls wieder über das Optionen-Objekt. In folgendem Beispiel wird die created()-Methode im Lebenszyklus überwacht und bei Aufruf die Nachricht geändert:

const app = Vue.createApp({
  data() {
    return {
      message: 'Hello Vue',
    };
  },
  methods: {
    changeMessage() {
      this.message = 'Vue rockt!';
    },
  },
  created() {
    this.message = "Changed message in created";
  },
});

Wer mag, kann mit console.log() Log-Meldungen in alle Hooks einbauen und so nachvollziehen, wie der Zyklus abgearbeitet wird. Typische Aufgaben, die in den Lebenszyklusmethoden durchgeführt werden, sind zum Beispiel das Laden von Daten über einen Webservice.

Es gibt weitere Optionen, die man beim Erzeugen der Vue-Instanz übergeben kann, und es gibt eine ganze Reihe weiterer Direktiven. Die Funktionsweise ist allerdings ähnlich und wird in den nächsten Beiträgen ausführlich besprochen.

(ID:47872595)