Vue.js: Zeitgemäße und wartbare JavaScript-Client-Anwendungen

Seite 2: View-, Input- und Event-Binding

Inhaltsverzeichnis

Das vorherige Beispiel nutzte bereits View-Binding, um Daten aus dem internen Modell der Vue-Komponente auf der Web-Page anzuzeigen. Das folgende Beispiel zeigt die weiteren Konzepte Input- und Event-Bindung sowie Conditionals. Der dazugehörige HTML-Teil ist dazu wie folgt zu erweitern:

<div id="app">
<p>{{ message }}</p> <!--1-->
<p v-if="message === ''"> <!--2-->
Please enter a Message!
</p>
<p>
<input v-model="message"> <!--3-->
</p>
<button v-on:click="reverseMessage">Reverse Message</button> <!--4-->
</div>
  1. Das View-Binding fĂĽr die Nachricht ist weiterhin auf der Seite enthalten.
  2. Wenn die eingegebene Nachricht leer ist, soll eine Meldung erscheinen. Das geschieht mit v-if.
  3. Der Inhalt aus message füllt ein Eingabefeld. Wenn der Nutzer eine Eingabe tätigt, aktualisiert sich das Modell (Event-Binding). Umgekehrt aktualisiert sich auch der Inhalt des Eingabefelds wenn sich das Modell ändert (View-Binding). Im Template ist die Kurzform mit v-model als Attribut hinzugefügt.
  4. Wenn der Nutzer auf den Button klickt, soll eine JavaScript-Methode den Text umdrehen. Dies geschieht mit dem Attribut v-on:click.

Auch der JavaScript-Code wird erweitert:

var app = new Vue({
el: '#app',
data: {
message: 'Hello Vue.js!'
},
methods: { // <1>
reverseMessage: function () {
this.message =
this.message
.split('')
.reverse().join('')
}
}
})

Ein zusätzliches Attribut methods enthält alle Methoden, die beispielsweise für Event-Bindings aufrufbar sind. In diesem Beispiel aktualisiert die Methode das Modell der Komponente: Die Buchstaben der Zeichenkette message füllen sich rückwärts.

Im Browser zeigt sich, wie komfortabel das Binding funktioniert. Ändert der Nutzer die Werte im Eingabefeld, passt sich die Anzeige darüber ebenfalls an. Klickt der Nutzer auf den Button, ändert sich sowohl die Anzeige als auch der Inhalt des Eingabefelds. Löscht der Nutzer den kompletten Inhalt des Eingabefelds, erscheint die Meldung, dass das Eingabefeld nicht leer sein darf.

Wie hier sollten beim Start der Komponente Werte in deren Modell initialisiert werden. Das ist Best-Practice und sorgt dafür, dass die Änderungserkennung von Vue.js automatisch funktioniert. Möchte man ein Attribut im Nachhinein im Modell ergänzen, muss man es mit Vue.set hinzufügen, da ansonsten die Änderungserkennung von Vue.js nicht funktioniert. Das ist eine Einschränkung, die sich aus der Unterstützung der JavaScript-Versionen älterer Browser ergibt.

In dieser ersten Ausbaustufe bietet Vue.js eine klare Trennung von View, Model und Logik. Die Bindings erlauben klar strukturierten und wartbaren Code. Dadurch lassen sich kleine, kompakte Erweiterungen realisieren. In der Vergangenheit setzten Entwicklungsteams dafĂĽr oft jQuery ein. Der Code mit Vue.js ist jedoch klarer und strukturierter.

Wächst die Anwendung, bietet sich als erste Strukturierung jeweils eine Komponente pro Dialog oder Seite an. Die Erweiterung vue-router kümmert sich um die Navigation zwischen den Seiten. Ein erstes Beispielprojekt ist mit vue-cli schnell erstellt. Dieser Artikel nutzt vue-cli in Version 3, das statt auf Templates auf Plug-ins beruht, die Entwickler mit einer Konfigurationsdatei parametrisieren können. Im Gegensatz zu Version 2 ist es möglich, Plug-ins nachträglich zu installieren, und Versionsupdates sind einfacher. Voraussetzung ist, dass Node und NPM installiert sind.

npm install -g @vue/cli
vue create ...

Danach ist die Anwendung im Entwicklungsmodus ausfĂĽhrbar:

npm run serve

Abbildung 1: Layout der Anwendung

Alle Quelldateien liegen im Unterverzeichnis src und public. Darunter befinden sich jeweils eigene Ordner fĂĽr statische Dateien, Grafiken und Komponenten.

Die Komponenten haben die Dateiendung .vue. Es sind Single File Components, die HTML, JavaScript und CSS für die jeweilige Komponente enthalten. Hierbei können Entwickler alle drei Elemente in einem Rutsch bearbeiten, anstatt immer drei Dateien gleichzeitig editieren zu müssen. Vue.js stellt dabei mit dem Schlüsselwort scoped sicher, dass das CSS nur für die jeweilige Komponente angewendet wird. Jedoch erfordert dies eine entsprechende Unterstützung innerhalb der IDE, damit in jedem der drei Teile die Syntax-Unterstützung für die jeweilige Sprache vorhanden ist. Bei JetBrains (IntelliJ, WebStorm, PHPStorm), VS Code und vielen anderen IDEs ist dafür ein passendes Plug-in verfügbar.

<template>
<div class="hello">
<!-- ... ->
</div>
</template>

<script>
export default {
/* ... */
}
</script>

<style scoped>
// ...
</style>

Damit Routing in der Anwendung funktioniert, sind einige Schritte notwendig:

Im Haupt-Template der Anwendung ist der Bereich zu definieren, der die Komponente der jeweiligen Route anzeigen soll.

<template>
<div id="app">
<router-view></router-view>
</div>
</template>

In der Routing-Datei ist für jede URL eine entsprechende Komponente hinterlegt. Später kann man hier auch URL-Parameter für die Routen definieren.

Vue.use(Router)

export default new Router({
routes: [
{
path: '/',
name: 'Hello',
component: Hello
},
{
path: '/counter',
name: 'Counter',
component: Counter
}
]
})

Ruft ein Nutzer nun einen Link auf, sorgt vue-router für eine automatische Aktualisierung der Seite. Auf Wunsch sind auch Transitions möglich, die zum Beispiel die alte Maske langsam aus- und die neue sanft einblenden. Das folgende Beispiel ergänzt ein einfaches Menü und fügt Transitions hinzu:

<template>
<div id="app">
<router-link class="router" to="/">Hello</router-link>
<router-link class="router" to="/counter">Counter</router-link>

<transition name="slide-fade" mode="out-in">
<router-view></router-view>
</transition>
</div>
</template>

<script>
/* ... */
</script>

<style>
.slide-fade-enter-active {
transition: all .3s ease;
}
.slide-fade-leave-active {
transition: all .8s cubic-bezier(1.0, 0.5, 0.8, 1.0);
}
.slide-fade-enter, .slide-fade-leave-to {
transform: translateX(10px);
opacity: 0;
}
</style>