Seit der Veröffentlichung von Vue.js 2 ist die Vue.js-Community schnell gewachsen und erhält von den Usern großartige Bewertungen. Neben Angular und React zählt es zu den beliebtesten JavaScript-Frameworks. Nun steht Vue.js 3 kurz vor der Veröffentlichung und hat in den letzten Monaten für einen ziemlichen Hype in der Welt der Webentwicklung gesorgt.

Verbesserungen

Die neue Version von Vue.js ist auf Geschwindigkeit ausgelegt. Obwohl Vue 2 schon relativ schnell war, hat Vue 3 eine bis zu 100% bessere Update-Leistung und bis zu 200% schnellere serverseitige Renderings. Auch die Komponenten-Initialisierung ist jetzt effizienter, sogar mit Compiler-informierten schnellen Pfaden zur Ausführung. Das virtuelle DOM wurde ebenfalls vollständig neu geschrieben und übertrifft in Sachen Geschwindigkeit seine alte Version deutlich.

Auch von der Größe her gibt es nun Verbesserungen. Vue 2 war mit einem Gewicht von etwa 20 kB gzipped bereits verdammt klein. Mit einer konstanten Gundliniengröße von < 10 kB gzipped wiegt Vue 3 nur noch halb so viel. Wie? Größtenteils durch Eliminieren nicht genutzter Bibliotheken (Tree Shaking). Wenn du also ein Element nicht verwendest, ist es nicht enthalten.

Vue 3 wird TypeScript unterstützen. Zusätzlich werden die Pakete entkoppelt, wodurch alles modularer und einfacher zu warten sein wird.

Das Erstellen nativer Anwendungen mit Vue ist gar nicht so schwierig, aber mit Vue 3 ist der Laufzeit-Kern plattformunabhängig, wodurch es noch einfacher wird, diese Technologie mit jeder Art von Plattform zu verwenden.

Wie du siehst, lohnt es sich mal anzuschauen, welche Neuerungen es bei Vue geben wird. Werfen wir nun einen Blick auf die wichtigsten Features von Vue 3.

Composition API

Bisher griffen wir beim Erstellen neuer Komponenten auf die Options API zurück. Diese API zwang uns, den Code der Komponente durch Optionen zu trennen, was bedeutete, dass wir alle reaktiven Daten an einer Stelle (Data), alle berechneten Eigenschaften an einer Stelle (Computed), alle Methoden an einer Stelle (Methods) usw. haben mussten.

Obwohl es zwar für kleinere Komponenten handlich und lesbar ist, wird es jedoch schmerzhaft, wenn die Komponente komplexer wird und mit mehreren Funktionalitäten zu tun hat. Gewöhnlich enthält die Logik, die sich auf eine bestimmte Funktionalität bezieht, einige reaktive Daten, berechnete Eigenschaften, eine Methode oder einige wenige davon; manchmal beinhaltet sie auch die Verwendung von Component-Lifecylcle-Hooks. Das führt dazu, dass man bei der Arbeit an einem einzigen logischen Anliegen ständig zwischen verschiedenen Optionen im Code hin- und herspringen muss.

Das andere Problem, auf das man bei der Arbeit mit Vue gestoßen sein könnte, ist die Frage, wie man eine gemeinsame Logik extrahieren kann, die von mehreren Komponenten wiederverwendet werden kann. Vue hat bereits wenige Optionen, um dies zu tun, aber alle haben ihre eigenen Nachteile (z.B. Mixins und Scoped-Slots).

Die Lösung von Vue 3 hierfür ist eine setup()-Methode, die es uns ermöglicht, die Kompositionssyntax zu verwenden. Jedes Stück Logik ist außerhalb dieser Methode als Kompositionsfunktion definiert.

Codebeispiel aus einem Color-Picking-Spiel unter Nutzung der Komposition API:

<script>
import Vue from "vue";
import ColorChoiceButton from "@/components/ColorChoiceButton";
import GameControlHeader from "@/components/GameControlHeader";
import { reactive } from "vue";
import { getRandomColor } from "@/utils/getRandomColor";
 
export default {
  components: {
    GameControlHeader,
    ColorChoiceButton
  },
  setup() {
    const score = reactive({
      lost: 0,
      won: 0
    });
 
    const colors = reactive({
      picked: "",
      right: "",
      choices: ["", "", ""]
    });
 
    function pickColor(color = "") {
      colors.picked = color;
      if (colors.picked === colors.right) {
        //round won
        score.won++;
      } else {
        //round lost
        score.lost++;
      }
    }
    function setFreshColors() {
      colors.choices[0] = getRandomColor();
      colors.choices[1] = getRandomColor();
      colors.choices[2] = getRandomColor();
 
      // we should detect the rare case that we get the same color twice and generate colors again
 
      const randomChoice = Math.round(Math.random() * 2);
      colors.right = colors.choices[randomChoice];
      colors.picked = "";
    }
    function resetGame() {
      score.won = 0;
      score.lost = 0;
      setFreshColors();
    } //new colors, score = 0
 
    resetGame();
 
    return { pickColor, resetGame, setFreshColors, score, colors };
  }
};
</script>

Kurz gesagt, es handelt sich lediglich nur um eine Funktion, die Properties und Funktionen an das Template zurückgibt. Wir deklarieren hier alle reaktiven Properties, computed Properties, Watchers und Lifecycle-Hooks und geben sie dann zurück, damit sie im Template verwendet werden können.

Die Composition API ist eine großartige Möglichkeit, Code lesbarer und wartbarer zu machen. Sie wird dazu beitragen, dass größere Vue-Projekte modularer und wiederverwendbarer sind; ein sehr vielversprechendes Zeichen für die entwicklerfreundlichen Änderungen, die das Vue-Team vornimmt. Es scheint, als hätten sie viele Schmerzpunkte der Entwicklerteams entdeckt und versucht, praktikable Lösungen anzubieten, ohne dabei extrem drastische Änderungen vorzunehmen.

Mehrere Root Elemente

In Vue 2 kann das Template-Tag nur ein Wurzelelement aufnehmen. Selbst wenn wir nur zwei <p>-Tags hätten, müssten wir sie in ein <div>-Tag einschließen, damit es funktioniert. Aus diesem Grund mussten wir auch den CSS-Code in der übergeordneten Komponente so ändern, dass er wie erwartet aussah.

In Vue 3 wird diese Einschränkung aufgehoben. Es wird kein Root-Element mehr benötigt.

Wir können eine beliebige Anzahl von Tags direkt innerhalb der Sektion <template></template> verwenden:

<template>
  <p> Count: {{ count }} </p>
  <button @click="increment"> Increment </button>
  <button @click="decrement"> Decrement</button>
</template>

Suspense

Suspense ist eine Komponente, die während des Lazy-Loadings benötigt wird, das im Wesentlichen dazu dient,  Lazy-Komponenten zu umhüllen. Mehrere Lazy-Komponenten können mit der Suspense-Komponente umwickelt werden. In der Version 3 von Vue JS wird Suspense eingeführt, um auf verschachtelte asynchrone Abhängigkeiten in einem verschachtelten Baum zu warten, und es funktioniert gut mit asynchronen Komponenten. Anstelle unserer Komponente wird ein Fallback-Content angezeigt, bis eine gewünschte Bedingung erfüllt ist. Die Bedingung ist in der Regel ein asynchroner Vorgang, der innerhalb unserer Komponenten-Setup-Funktion stattfindet.

Beispiel:

<Suspense>
  <template >
    <suspended-component />
  </template>
  <template #fallback>
    Loading...
  </template>
</Suspense>

Portals

Die <teleport to=”target”>-Komponente verschiebt alle Children zum ersten durch target beschriebenen Element im DOM-Tree. Dabei funktioniert target wie ein herkömmlicher Query-Selektor, das heißt, ein Element kann über die ID (#target), die Klasse (.target) oder den Tag-Namen (z.B. main) angewählt werden.

Mit Teleports können sich vor den Content stellende Elemente wie Modals, (Cookie) Banners, Pop Ups etc. von überall aus in der App aufgerufen werden, rendern aber stets an derselben Stellen im DOM-Tree.

App.vue

<Component>
  <teleport to="#target">
    <div>...</div>
  </teleport>
</Component>

index.html

<body>
  ...
  <div id="app"></div>
  <div id="portal-target"></div>
</body>

Multiple V-Models

Wenn du Vue verwendest, weißt du bereits, dass v-models für die bidirektionale Datenbindung von Vue-Komponenten verwendet werden. In Vue 2 erhältst du ein v-model für eine Komponente, aber in dieser neuen Version gibt es tolle Neuigkeiten!

Du kannst jetzt so viele v-model-Deklarationen und -Bindungen pro Komponente haben wie du willst und die einzelnen v-models auch benennen.

So etwas ist jetzt möglich:

<InviteeForm
   v-model:name="inviteeName"
   v-model:email="inviteeEmail"
/>

Global mounting/configuration API Änderung

Wir können eine weitere wichtige Änderung in der Art und Weise finden, wie wir unsere Anwendung instanziieren und konfigurieren. Derzeit verwenden wir das globale Vue-Objekt, um jede beliebige Konfiguration bereitzustellen und neue Vue-Instanzen zu erstellen. Jede am Vue-Objekt vorgenommene Änderung wirkt sich auf jede Vue-Instanz und Komponente aus.

Schauen wir uns nun an, wie es in Vue 3 funktionieren wird:

import { createApp } from 'vue'
import App from './App.vue'
 
const app = createApp(App)
 
app.config.ignoredElements = [/^app-/]
app.use(/* ... */)
app.mixin(/* ... */)
app.component(/* ... */)
app.directive(/* ... */)
 
app.mount('#app')

Fazit

Abgesehen von der Composition API, welche die größte neue API in Vue 3 ist, können wir auch eine Menge kleinerer Verbesserungen finden. Wir können sehen, dass sich Vue in Richtung einer besseren Erfahrung für Entwickler und einfachere, intuitivere APIs bewegt. Es ist auch großartig zu sehen, dass das Vue-Team beschlossen hat, viele Ideen, die derzeit nur über Bibliotheken von Drittanbietern verfügbar sind, in den Kern des Frameworks zu übernehmen.