© DimaSid/Shutterstock.com
Formulare und Navigation mit dem Vue Router

Immer auf dem richtigen Pfad


Diesmal geht es in unserer Reihe zu Vue um die Navigation innerhalb einer Applikation. In einer Single Page Application haben Sie ja grundsätzlich das Problem, dass ein Neuladen der Seite beziehungsweise das Navigieren von einer Unterseite zu einer anderen den lokalen State der Applikation im Browser zurücksetzt. Um das zu vermeiden, existieren für alle modernen Frontend Frameworks Erweiterungen, die eine Navigation zwischen verschiedenen Ansichten und damit unterschiedlichen Komponentenbäumen ermöglichen.

Zur Demonstration der Implementierung einer Navigation innerhalb von Single Page Applications erweitern wir zunächst die To-do-Applikation aus den ersten beiden Teilen der Reihe (siehe Entwickler Magazin 4.18 und 1.19) um ein Formular zum Erstellen und Modifizieren von To-dos und steuern es anschließend mit dem Vue Router an. Bevor Sie das Routing für Ihre Applikation implementieren, muss eine Möglichkeit zur Erzeugung von Datensätzen in die Anwendung eingefügt werden. Dazu generieren Sie eine neue Komponente, die Sie unterhalb der To-do-Liste anzeigen. Hierbei handelt es sich um ein einfaches Formular, über das Sie den Titel und den Status einer Aufgabe eingeben können. Wie das in der Applikation aussehen soll, sehen Sie in Abbildung 1.

springer_vue_router_1.tif_fmt1.jpgAbb. 1: Inline-Formular zur Erzeugung neuer Aufgaben

Formulare werden von Vue nativ unterstützt [1]. Das bedeutet, dass Sie keinerlei zusätzliche Pakete installieren müssen. Die wichtigste Funktionalität einer Frontend-Bibliothek wie Vue im Zusammenhang mit Formularen ist die Synchronisierung der Formulareingaben mit den Datenstrukturen der Komponenten. Diese Aufgabe erfüllt die v-model-Direktive. Sie übernimmt das Two-Way Data Binding, über das die Eigenschaften der Komponente mit dem Formular synchronisiert werden.

Neue Aufgaben erzeugen

Der erste Schritt der Implementierung besteht aus der Erzeugung der Formularkomponente. Zunächst legen Sie eine Datei mit dem Namen Form.vue im components-Verzeichnis der Applikation an. Auch diese folgt der Konvention der Single File Components mit der Dreiteilung in Template, JavaScript-Code und Styling. Den Quellcode der Komponente finden Sie in Listing 1.

Listing 1: Die „form“-Komponente

<template> <form @submit.prevent="handleSubmit"> <input autofocus id="title" name="title" type="text" v-model="title" placeholder="Neue Aufgabe erstellen" > <select id="done" name="done" v-model="done"> <option :value="false">offen</option>> <option :value="true">erledigt</option>> </select> <button type="submit">OK</button> </form> </template> <script> import { createNamespacedHelpers } from "vuex"; const { mapActions } = createNamespacedHelpers("todo"); import { CREATE_TODO } from "../todo"; export default { methods: { ...mapActions({ createTodo: CREATE_TODO }), handleSubmit() { this.createTodo({ title: this.title, done: this.done }); this.title = ""; this.done = false; } }, data() { return { title: "", done: false }; } }; </script> <style scoped> ... </style>

Das Template der Komponente besteht im Kern aus einem Formularelement. An dessen Submit-Event wird die handleSubmit-Methode gebunden. Durch die Erweiterung .prevent des Event-Attributs wird verhindert, dass die Standardaktion, also das Absenden des Formulars, ausgeführt wird. Das Formular besteht aus drei Elementen: einem Eingabefeld für den Titel der Aufgabe, einem Drop-down-Menü für den Status, also ob die Aufgabe noch offen oder bereits erledigt ist, und schließlich einem Button zum Abschicken des Formulars.

Das wichtigste Element des Eingabefelds ist die v-model-Direktive. Der Wert title verbindet das Eingabefeld mit der title-Eigenschaft der Komponenteninstanz. Sobald Sie den Wert im Formularelement ändern, wird auch automatisch der Wert in der Komponenteninstanz synchronisiert. Die Synchronisierung erfolgt bei jedem Input-Event. Dieses Verhalten können Sie mit Hilfe der .lazy-Erweiterung von v-model ändern, sodass die Synchronisierung erst beim Change Event erfolgt. Die übrigen Attribute entsprechen denen eines gewöhnlichen HTML-Input-Elements. Das autofocus-Attribut sorgt dafür, dass der Fokus standardmäßig auf diesem Element liegt und der Benutzer direkt mit der Eingabe starten kann. Der Placeholder informiert den Benutzer über den Inhalt des Eingabefelds. Ähnlich wie das Eingabefeld funktioniert auch die Verarbeitung des Drop-down-Menüs. Allerdings müssen Sie hier darauf achten, dass die done-Eigenschaft einen booleschen Wert annehmen soll. Mit Hilfe der Angabe von v-bind:value oder mit der Kurzform :value können true oder false an die jeweiligen Optionen gebunden werden.

Die Applikation benutzt für das State Management Vuex, also müssen Sie das Formular mit dem Store der Applikation verbinden. Das Hinzufügen einer neuen Aufgabe erfolgt, indem die Formularkomponente eine neue Action auslöst, die im Store abgefangen und verarbeitet wird. Mit Hilfe der mapActions-Funktion aus dem vuex-Paket kann eine solche Action, die im Beispiel die Bezeichnung CREATE_TODO trägt, über eine lokale Methode der Komponente getriggert werden. Die Konstante, die für die Action steht, wird mit dem Alias createTodo versehen, der den Methodennamen innerhalb der Komponente darstellt. Die bereits erwähnte handleSubmit-Methode der Komponente erzeugt ein Objekt, das für die zu erstellende Aufgabe steht und übergibt dieses an die createTodo-Methode. Nach dem Aufruf dieser Methode weisen Sie den Eigenschaften title und done Standardwerte zu, die dazu führen, dass das Formular in seinen Ursprungszustand zurückgesetzt wird, sodass der Benutzer wieder eine neue Aufgabe anlegen kann. Mit diesen Anpassungen und noch ein wenig Styling ist die Formularkomponente fertiggestellt. Allerdings ist sie aus zwei Gründen noch nicht funktionsfähig: Noch ist sie nicht in die Applikation eingefügt und die Gegenseite im Vuex-Store ist ebenfalls noch nicht umgesetzt.

Einbindung der Formularkomponente in die Applikation

Die Integration der Formularkomponente in die Applikation erfolgt in der TodoList-Komponente, da das Formular als letztes Element in der Liste angezeigt werden soll. Hierfür müssen Sie die Komponente zunächst importieren und anschließend in der Eigenschaft components registrieren. Im letzten Schritt fügen Sie das Form-Tag, das für die Komponente steht, in das Template ein (Listing 2). Eine Übergabe von Props ist hier nicht erforderlich, da die form-Komponente direkt mit dem Store verbunden und somit unabhängig von der Elternkomponente ist.

Listing 2: Einbindung der „form“-Komponente in die Applikation

<template> <div> <Button v-on:click="toggleFilter()">Filter</Button> <ul> <TodoListItem v-for="todo in getTodos()" v-bind:todo="todo" v-bind:key="todo.id"></TodoListItem> </ul> <Form/> </div> </template> <script> import TodoListItem from "./TodoListItem.vue"; import Form from "./Form.vue"; import { createNamespacedHelpers } from "vuex"; import { GET_TODOS } from "../todo"; const { mapState, mapGetters, mapActions } = createNamespacedHelpers("todo"); export default { name: "TodoList", components: { TodoListItem, Form }, data() {…}, methods: {…}, computed: {…}, mounted() {…} }; </script>

Einbindung in den Vuex-Store

Der letzte Schritt, mit dem Sie die Funktionsfähigkeit der form-Komponente sicherstellen, ist die Einbindung in den Vuex-Store. Zunächst benötigen Sie hier zwei Konstanten, die für die Actions stehen. Die erste Action wird aus den Komponenten der Applikation heraus ausgelöst, um eine neue Aufgabe zu erzeugen. Die zweite Action, CREATE_TODO_SUCCESS, steht für eine erfolgreiche Antwort des Webservers, nachdem die Aufgabe erzeugt wurde. Diese nutzen Sie, um den Store zu aktualisieren. Beide Action-Konstanten werden exportiert, sodass Sie aus anderen Komponenten, wie beispielsweise der form-Komponente, darauf zugreifen können.

Die bestehenden Actions ergänzen Sie um einen Eintrag für CREATE_TODO. In dieser Methode haben Sie Zugriff auf die commit-Funktion und die Informationen der übergebenen Aufgabe. Innerhalb dieser Methode kommunizieren Sie mit dem Server und schicken die Daten an ihn. Sobald die Antwort des Servers vorliegt, lösen Sie die CREATE_TODO_SUCCESS-Action aus. Um die neu erzeugte Aufgabe anzuzeigen, müssen Sie noch die Mutations erweitern, um mit der CREATE_TODO_SUCCESS-Action umzugehen. An dieser Stelle pushen Sie die neue Aufgabe. Daraufhin wird die Anzeige aktualisiert und die Aufgabe erscheint in der Anzeige (Listing 3).

Listing 3: Der Vuex-Store

import Vue from 'vue'; const initialState = { todos: [] }; export const TOGGLE_DONE = 'TOGGLE_DONE'; export const TOGGLE_DONE_SUCCESS = 'TOGGLE_DONE_SUCCESS'; export const GET_TODOS = 'GET_TODOS'; export const GET_TODOS_SUCCESS = 'GET_TODOS_SUCCESS'; export const CREATE_TODO = 'CREATE_TODO'; export const CREATE_TODO_SUCCESS = 'CREATE_TODO_SUCCESS'; export default { namespaced: true, state: initialState, getters: {…}, mutations: { [TOGGLE_DONE_SUCCESS](state, m...

Neugierig geworden? Wir haben diese Angebote für dich:

Angebote für Gewinner-Teams

Wir bieten Lizenz-Lösungen für Teams jeder Größe: Finden Sie heraus, welche Lösung am besten zu Ihnen passt.

Das Library-Modell:
IP-Zugang

Das Company-Modell:
Domain-Zugang