Komplexe Webanwendungen mit Vue.js, Teil 1

Seite 2: Komponenten

Inhaltsverzeichnis

Eine Vue.js-Anwendung ist aus einer Hierarchie von Komponenten aufgebaut. FĂĽr eine neue Anwendung mĂĽssen Entwickler frĂĽh entscheiden, wie sie die gewĂĽnschten Funktionen sinnvoll in diese unterteilen, ohne eine einzelne zu umfangreich anzulegen. Die Konfiguration der Komponente geschieht ĂĽber ein Objekt, das innerhalb von SFCs als JavaScript-Modul exportiert wird. AuĂźerhalb von SFCs kann man Komponenten per Vue.component registrieren.

Wie zuvor gezeigt, ist die oberste Komponente innerhalb der Hierarchie die explizit per new Vue initialisierte Vue-Instanz. Auch alle anderen Komponenten der Anwendung sind Vue-Instanzen, wobei sich bei mehrfacher Nutzung einer Komponente alle Auftritte eine Vue-Instanz teilen. Damit sie trotzdem einen privaten Zustand haben, initialisiert man die Properties über eine anonyme Funktion, die ein Objekt zurückgibt. Alle im Objekt definierten Attribute fügt Vue.js der Änderungsverfolgung (Change Detection) hinzu.

Um Änderungen zu überwachen, registriert Vue.js für alle Properties interne Getter- und Setter-Funktionen. Das ermöglicht es Vue.js, alle Änderungen effizient zu verfolgen, ohne einen Vorher-Nachher-Vergleich durchführen zu müssen (Dirty Checking). Das Prinzip hat aber zur Folge, dass es notwendig ist, alle benötigen Properties im Datenmodell vorab zu definieren, um sie automatisch zu erkennen. Möchte man zur Laufzeit Properties hinzufügen, kann man sie per Vue.set registrieren.

Die wichtigsten Definitionsangaben fĂĽr eine Komponente sind:

  • data: anonyme Funktion, die die Datenattribute der Komponente als Objekt zurĂĽckgibt.
  • props: Angabe der Input-Parameter der Komponente. Optional ist die zusätzliche Definition des erwarteten Datentyps und eine Unterscheidung in optionale und Pflichtparameter möglich
  • components: die lokal zu verwendenden Komponenten. Global registrierte Komponenten muss man hier nicht erneut auffĂĽhren.
  • computed: Angabe von berechneten Funktionen. Sie laufen synchron ab und Vue.js hält sie automatisch aktuell.
  • watch: Watcher-Funktionen, die die Ă„nderung eines ĂĽberwachten Werts aufruft. Grundsätzlich sind Computed Properties zu bevorzugen, da sie gepuffert werden und performanter sind. FĂĽr Anwendungsfälle, in denen Computed Properties keine Verwendung finden können, beispielsweise bei asynchronen Aufrufen, sind Watch-Funktionen geeignet.
  • Lifecycle-Callbacks: Vue.js definiert mehrere Lifecycle-Callbacks, die entsprechende Lebenszyklen der Komponente hervorrufen: created, mounted, updated und weitere.
  • methods: beliebige eigene Funktionen.

Ein einfaches Beispiel:

export default {
name: "PercentageCounter",
data() {
return {
percentageCount: 0
}
},
props: {
initialPercentageCount: Number,
factor: {
type: Number,
required: true
}
},
computed: {
absoluteValue: function() {
if (this.percentageCount && this.factor)
return this.percentageCount * this.factor
return 0
}
},
watch: {
percentageCount: function(val) {
if (val && val === 100) {
this.setDone()
}
}
},
created() {
if (this.initialPercentageCount)
this.percentageCount = this.initialPercentageCount
},
methods: {
increase() {
this.percentageCount++
},
setDone() {
this.$emit("done", this.absoluteValue)
}
}
}

Zunächst initialisiert man die Eigenschaft percentageCount mit 0 und definiert daraufhin die beiden Props initialPercentageCount und factor. Beide erwarten den Datentyp Number, aber factor ist ein Pflichtwert. Die berechnete Eigenschaft absoluteValue berechnet das Produkt aus factor und percentageCount.

Weiterhin ist eine Watch-Methode fĂĽr die Eigenschaft percentageCount definiert. Sie ĂĽberprĂĽft, ob der Wert 100 erreicht ist und ruft im positiven Fall die Methode setDone auf.

Der created-Callback übernimmt initialPercentageCount nach percentageCount, falls es übergeben wurde. Am Ende sind zwei eigene Methoden definiert: increase erhöht percentageCount und setDone gibt den berechneten Wert absoluteValue zurück.

Die Komponente können Entwickler im Template der übergeordneten Komponente beispielsweise wie folgt verwenden:

<PercentageCounter v-bind:initialPercentageCount="98" 
v-bind:factor="1.67" v-on:done="counterDone"/>

Alternativ sind v-bind und v-on durch eine kĂĽrzere Syntax ersetzbar:

<PercentageCounter :initialPercentageCount="98" 
:factor="1.67" @done="counterDone"/>

Vue.js unterstĂĽtzt bidirektionales Databinding (two-way) mit der Direktive v-model. Sie kann ein Input-Control mit einem Attribut im Datenmodell verknĂĽpfen. Vue.js sorgt dafĂĽr, dass sie synchron bleiben.

<input v-model="percentageCount" type="string">

Vue.js hat keine eingebauten Validatoren fĂĽr Eingabefelder, aber es gibt ausgereifte Community-Varianten. Die bekanntesten sind Vuelidate und VeeValidate.

Zum Absenden eines HTML-Formulars wird das Submit-Event verwendet und eine eigene Funktion registriert. Der Modifier prevent verhindert das Auslösen der normalen Übertragung an den Server.

<form v-on:submit.prevent="mySubmitMethod"> 
<input v-model="percentageCount" type="string">
<button type="submit">Senden</button>
</form>

Nach diesem Prinzip ist jede Vue.js-Anwendung aus einer Hierarchie von Komponenten aufgebaut. Größere Anwendungen benötigen jedoch weitere Mechanismen, um Redundanzen zu vermeiden und die Anwendung langfristig wartbar zu halten.