Vue.js unter der Lupe, Teil 2: VueX

Vue.js unter der Lupe: State Management mit VueX
Keine Kommentare

In dieser Tutorial-Reihe nehmen wir das JavaScript-Framework Vue.js genau unter die Lupe. Nach dem Blick auf die Komponentenkommunikation schauen wir uns jetzt das State Management in Vue.js an: Die Library VueX.

Vue.js unter der Lupe: VueX

VueX ist die offizielle Bibliothek für das State Management in Vue.js. VueX ist dazu da, Daten zwischen den Komponenten einer Anwendung zu teilen. Vue-Komponenten können out-of-the-box auf zwei Arten kommunizieren:

  • Per Props, um den Zustand einer Parent-Komponente an eine Child-Komponente zu übergeben
  • Events, um den Zustand einer Parent-Komponente von einer Child-Komponente aus zu verändern oder indem die Root-Komponente als Event Bus benutzt wird

Manchmal werden die Dinge jedoch komplexer als das, was diese simplen Optionen zulassen. In diesem Fall ist es eine gute Option, den Zustand in einem Store zu zentralisieren. Genau das ist es auch, was Vue macht.

 

Vue.js unter der Lupe: Warum Sie VueX einsetzen sollten

VueX ist nicht die einzige Option für das State Management, die man mit Vue verwenden kann (Redux ist auch möglich). Der größte Vorteil an VueX ist aber, dass es die offizielle Option ist und vor allem durch seine Integration mit Vue hervorsticht. Bei React ist das Problem hingegen, dass man sich selbst für eine Option entscheiden muss, da das Ökosystem sehr groß ist und de facto keinen Standard besitzt. In letzter Zeit war Redux jedoch die beliebteste Wahl, gefolgt von MobX, im Hinblick auf die Beliebtheit. Bezüglich Vue würde ich aber sogar so weit gehen zu sagen, dass man sich nach keiner Alternative zu VueX umsehen muss, vor allem nicht zu Beginn.

Vuex hat viele seiner Ideen von dem Ökosystem Reacts übernommen: Das Flux-Pattern, das durch Redux beliebt wurde. Sollten Sie sich bereits mit Flux oder Redux auskennen, so wird Ihnen VueX sehr vertraut sein. Und sollte das nicht der Fall sein, kein Problem – ich werde jedes der Konzepte von Grund auf erklären.

Komponenten in einer Vue-Applikation können einen eigenen Zustand haben. Zum Beispiel speichert ein Eingabefeld die dort eingefügten Daten lokal. Das funktioniert sehr gut; Komponenten können auch bei Verwendung von VueX einen lokalen Zustand haben. Wenn man viel Aufwand betreiben muss um Zustände weiter zu geben, weiß man, dass man VueX braucht. VueX stellt für diesen Anwendungsfall ein zentrales Repository für den Zustand zur Verfügung. Zustände werden verändert, indem man den Store dazu aufordert, das zu machen. Alle Komponenten, die von einem bestimmten Zustand abhängig sind, greifen darauf über Getter zu, der sicherstellt, dass die Komponente aktualisiert wird, sobald sich etwas verändert.

VueX fügt Anwendungen etwas Komplexität hinzu, weil es ein spezifisches Setup benötigt damit alles richtig funktioniert. Wenn VueX aber dabei hilft, das Problem der unorganisierten Übergabe von Props zu lösen und das Event-System zu organisieren, das sonst zu Spaghetti-Code werden kann, wenn es zu kompliziert wird, ist es eine gute Wahl.

State Management mit VueX: Los geht’s!

In diesem Beispiel beginne ich mit einer Vue CLI-Applikation. VueX kann ebenfalls direkt über ein Script-Tag geladen und genutzt werden. Da VueX aber eher auf größere Applikationen ausgelegt ist, ist es wahrscheinlicher, dass es in einer stärker strukturierten App zur Anwendung kommt, die man mit dem Vue CLI aufsetzen kann.

Die Beispiele, die ich hier verwende, sind in CodeSandbox  geschrieben, einem großartigen Service, der ein einsatzbereites Vue CLI-Beispiel unter https://codesandbox.io/s/vue anbietet. Ich empfehle, damit herumzuspielen.

Sobald Sie das Beispiel geöffnet haben, klicken Sie auf die Add dependency-Schaltfläche, geben „vuex“ ein und klicken es an. Jetzt wird VueX als Dependency aufgelistet.

Um VueX lokal zu installieren, können Sie einfach npm install vue oder yarn add vuex innerhalb des Projektordners ausführen.

VueX Store erstellen

Jetzt können wir unseren VueX Store erstellen.

Diese Datei kann überall abgelegt werden. Im allgemeinen wird empfohlen, sie in der src/store/store.js-Datei abzulegen, also machen wir das auch einfach.

Wir initialisieren VueX in dieser Datei und sagen dann zu Vue, dass es damit arbeiten soll:

import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export const store = new Vuex.Store({})

Wir exportieren ein VueX Store-Objekt, das wir mit der Vuex.Store()-API erstellt haben.

Ein Anwendungsfall für den Store

Jetzt, da wir ein Grundgerüst an Ort und Stelle haben, denken wir uns einen guten Anwendungsfall für VueX aus um die Konzepte einzuführen.

Ich nehme beispielsweise zwei Geschwisterkomponenten, eine mit einem Eingabefeld und eine, die den Inhalt des Eingabefelds ausgibt.

Wenn das Eingabefeld verändert wird, dann möchte ich auch den Inhalt in dieser zweiten Komponente verändern. Das ist sehr simpel, aber völlig ausreichend für unsere Aufgabe.

Erstellen der benötigten Komponenten

Ich lösche die HelloWorld-Komponente und füge eine Formular-Komponente und eine Display-Komponente ein.

<template>
<div>
<label for="flavor">Favorite ice cream flavor?</label>
<input name="flavor">
</div>
</template>
<template>
<div>
<p>You chose ???</p>
</div>
</template>

Einfügen dieser Komponenten zu der Applikation

Wir fügen sie dem App.vue-Code hinzu, statt der HelloWorld-Komponente:

<template>
<div id="app">
<Form/>
<Display/>
</div>
</template>
<script>
import Form from './components/Form'
import Display from './components/Display'
export default {
name: 'App',
components: {
Form,
Display
}
}
</script>

Den Zustand zum Store hinzufügen

Jetzt, da alles an seinem Platz ist, gehen wir zurück zu der store.js-Datei und fügen dem Store eine Eigenschaft hinzu, die state genannt wird und ein Objekt ist, das die flavor-Eigenschaft beinhaltet. Anfangs ist das ein leerer String.

import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export const store = new Vuex.Store({
state: {
flavor: ''
}
})

Es wird aktualisiert, wenn der Benutzer in das Eingabefeld schreibt.

Eine Mutation hinzufügen

Der Zustand kann nicht manipuliert werden, außer es werden Mutationen eingesetzt. Wir stellen eine Mutation bereit, die in der Formular-Komponente benutzt wird, um den Store darüber zu benachrichtigen, dass der Zustand verändert werden soll.

import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export const store = new Vuex.Store({
state: {
flavor: ''
},
mutations: {
change(state, flavor) {
state.flavor = flavor
}
}
})

Getter hinzufügen, um eine Zustandseigenschaft zu referenzieren

Nachdem das eingerichtet ist, müssen wir einen Weg hinzufügen, um den Zustand einzusehen. Das machen wir, indem wir getters benutzen. Wir richten daher ein getter für die flavor-Eigenschaft ein:

import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export const store = new Vuex.Store({
state: {
flavor: ''
},
mutations: {
change(state, flavor) {
state.flavor = flavor
}
},
getters: {
flavor: state => state.flavor
}
})

Beachten Sie, dass getters ein Objekt ist. flavor ist eine Eigenschaft dieses Objektes, die den Zustand als Parameter akzeptiert und die flavor-Eigenschaft des Zustands zurückgibt.

Vue Store zur App hinzufügen

Der Store ist jetzt bereit für die Verwendung. Wir gehen zurück zu unseren Applikationscode und müssen den Status in der main.js-Datei importierten und in unserer Vue Applikation verfügbar machen.

Wir fügen folgendes hinzu:

import { store } from './store/store'

Zur Vue-Anwendung wird das so hinzugefügt:

new Vue({
el: '#app',
store,
components: { App },
template: ''
})

Da dies die wichtigste Vue-Komponente ist, wird die store-Variable in jeder Vue-Komponente auf den VueX Store zeigen, sobald wird das erledigt haben.

Den Zustand einer User-Aktion mit Commit aktualisieren

Jetzt wollen wir den Status aktualisieren, wenn ein  Nutzer etwas tippt.

Das machen wir, indem wir das store.commit-API benutzen.

Aber zuerst erstellen wir eine Methode, die aufgerufen wird, wenn sich der Inhalt der Eingabe verändert. Wir benutzen dafür @input, nichtchange, da letzteres nur dann aktiviert wird, wenn der Fokus von dem Eingabefeld wegbewegt wird, während @input bei jedem Tastendruck aufgerufen wird.

<template>
<div>
<label for="flavor">Favorite ice cream flavor?</label>
<input @input="changed" name="flavor">
</div>
</template>
<script>
export default {
methods: {
changed: function(event) {
alert(event.target.value)
}
}
}
</script>

Jetzt, da wir den Wert von flavor haben, benutzen wir das VueX-API:

<script>
export default {
methods: {
changed: function(event) {
this.$store.commit('change', event.target.value)
}
}
}
</script>

Sehen Sie, wie wir den Store mit this.$store referenzieren? Das ist darum möglich, weil das Store-Objekt in der Initialisierung der Vue-Hauptkomponente enthalten ist.

Die commit()-Methode akzeptiert einen Mutation Name (wir haben change im Vue Store benutzt) und einen Payload, der als zweiter Paramter für die Callback-Funktion an die Mutation weitergegeben wird.

Getter benutzen, um die Statuswerte zu drucken

Jetzt müssen wie den getter dieses Wertes in der Darstellungsvorlage referenzieren, indem wir $store.getters.flavor benutzen. this kann entfernt werden, da wir in der Vorlage sind und da this implizit ist.

<template>
<div>
<p>You chose {{ $store.getters.flavor }}</p>
</div>
</template>

Vue.js unter der Lupe: VueX – Fazit

Das war’s auch schon mit der Einführung zu VueX!

Der vollständige, funktionierende Quellcode ist unter https://codesandbox.io/s/zq7k7nkzkm verfügbar.

Es fehlen immer noch viele Konzepte in diesem Puzzel:

  • Aktionen
  • Module
  • Helfer
  • Plug-Ins

Aber Sie haben die Grundlagen zum weiterarbeiten und können alles andere ja auch in den offiziellen Dokumenten nachlesen.

Frohes Coden!


Dieser Artikel erschien zuerst im Vue Handbuch von Flavio Copes.

International PHP Conference

Testing React Applications

by Hans-Christian Otto (Suora GmbH)

Building a Robo-Army with Angular

by Sebastian Witalec (Progress)

API Summit 2018

From Bad to Good – OpenID Connect/OAuth

mit Daniel Wagner (VERBUND) und Anton Kalcik (business.software.engineering)

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 -