Das JavaScript-Framework Vue.js, Teil 11 Formulare mit Vuetify erstellen
Anbieter zum Thema
Wie die UI-Bibliothek Vuetify funktioniert, haben wir bereits besprochen. Nun wollen wir ein typisches Kontaktdatenformular entwickeln, das verschiedene Vuetify-Komponenten beinhaltet und Eingaben auch validiert.

Der grundlegende Aufbau einer Vue-Anwendung mit der UI-Bibliothek Vuetify war Thema des vorangegangenen Artikels dieser Reihe. Vuetify-Formulare werden am besten innerhalb der Form-Komponente (v-form) formuliert, das erleichtert die spätere Validierung:
<v-form>
...
</v-form>
Innerhalb dieses Elements werden die verschiedenen Formularzeilen mithilfe des Vueitfy-Grid-Systems beschrieben. Wer bereits mit Bootstrap gearbeitet hat, kennt die Vorgehensweise. Die Zeile (v-row) für Vor-und Nachname beispielsweise soll auf einem hinreichend großen Display die beiden Eingabefelder (v-text-field) in gleicher Größe enthalten.
Nur auf sehr kleinen Displays (Extra small) bricht das Layout um: Hier sollen Vor- und Nachname jeweils die gesamte Spalte füllen. Default für eine Spalte ist also 12 Columns, ab Small (und größer) dann nur noch 6 Columns. Der dazugehörige Code sieht folgendermaßen aus:
<template>
<v-form>
<v-container>
<v-row>
<v-col cols="12" sm="6">
<v-text-field label="Vorname" v-model="firstname" maxlength="20" />
</v-col>
<v-col cols="12" sm="6">
<v-text-field label="Nachname" v-model="lastname" maxlength="20" />
</v-col>
</v-row>
</v-row>
</v-container>
</v-form>
</template>
Die Eingabe wird hier durch das Attribut maxlength auf 20 Zeichen beschränkt. Für die Angabe von Straße und Hausnummer wird das Größenverhältnis in der nächsten Zeile auf 3:1 geändert, die Straße belegt dann 9 Spalten, die Hausnummer dagegen nur noch 3:
<v-row>
<v-col cols="12" sm="9">
<v-text-field label="Straße" v-model="street" maxlength="20" />
</v-col>
<v-col cols="12" sm="3">
<v-text-field label="Hausnummer" v-model="no" maxlength="6" />
</v-col>
</v-row>
Auch in diesem Fall wird auf Displays, die kleiner als sm (Small) sind, der Defaultwert 12 mit einer ganzen Zeile pro Textfeld angewendet.
Regeln
Alle bisher definierten Textfelder sollen Pflichtfelder sein. Das lässt sich mit Hilfe einer Regel (Rule) sicherstellen, wie sie für alle Eingabeelemente in Formularen definiert werden kann. Regeln beschreiben Bedingungen, unter denen die Eingabe gültig bzw. ungültig ist und werden bei jeder Änderung des Werts der Komponente erneut ausgewertet. Die gewünschten Regeln werden in einem Array in der Prop rules aufgeführt:
<v-text-field label="Vorname" v-model="firstname" maxlength="20" :rules="[rules.required]" />
...
<script>
export default {
data() {
return {
email: "",
...
rules: {
required: value => !!value || 'Pflichtfeld',
},
};
},
};
</script>
Bei Verletzung dieser Regel wird der hinterlegte String (hier Pflichtfeld) in der Komponente in roter Farbe angezeigt, um den Benutzer auf das Problem hinzuweisen. In Kombination mit regulären Ausdrücken lassen sich mit Regeln auch komplexe Eingabefelder wie E-Mail oder Telefonnummer auf valide Eingaben überprüfen:
<v-text-field label="Email" v-model="email" :rules="[rules.email]"/>
...
rules: {
required: value => !!value || 'Pflichtfeld',
email: (value) => {
const pattern =
/^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
return pattern.test(value) || "Ungültige Email";
},
},
Die Textfeld-Komponente existiert übrigens in verschiedenen Ausprägungen, die sich über das Attribut type konfigurieren lassen. Mit dem Typ number kann man die Eingabe auf Zahlen beschränken und mit min, max Grenzwerte sowie mit step Schrittweiten bestimmen. Diese und viele weitere Informationen finden sich in der ausführlichen Dokumentation zu v-text-field.
Selektion von Werten
Zur Auswahl von Werten stellt Vuetify die Select-Komponente (v-select) zur Verfügung. Die möglichen Optionen werden in Form eines Arrays in der Prop items zur Verfügung gestellt. Hier sind das verschiedene Länder:
<v-select :items="countries" label="Land" v-model="country"></v-select>
Zur Auswahl der Rechnungsadresse (Lieferadresse oder abweichend) werden RadioButtons in Form der Komponente v-radio eingesetzt. Die Gruppierung erfolgt mithilfe einer umschließenden v-radio-group. Der ausgewählte Wert (hier einfach 1 oder 2) wird in diesem Fall in billingAddress geschrieben:
<v-radio-group v-model="billingAddress"> <v-radio :label="'Rechnungsadresse entspricht Lieferadresse'" :key="1" :value="1"/> <v-radio :label="'Abweichende Lieferadresse '" :key="2" :value="2"/> </v-radio-group>
Datumsauswahl leicht gemacht: DatePicker
Schließlich soll die Komponente v-date-picker zur Angabe des Geburtsdatums genutzt werden. Sie wird mit einem Textfeld kombiniert, das das gleiche v-model nutzt:
<v-row>
<v-col cols="12">
<v-menu
v-model="menu"
:close-on-content-click="false"
transition="scale-transition"
offset-y
min-width="auto">
<template v-slot:activator="{ on, attrs }">
<v-text-field
v-model="birthdate"
label="Geburtsdatum"
hint="MM/DD/YYYY format"
persistent-hint
prepend-icon="mdi-calendar"
v-bind="attrs"
v-on="on">
</v-text-field>
</template>
<v-date-picker
v-model="birthdate"
no-title
@input="menu = false">
</v-date-picker>
</v-menu>
</v-col>
</v-row>
Die Menu-Komponente um Textfield und DatePicker sorgt dafür, dass der Picker an der Position des Textfeldes geöffnet wird. Alternativ könnte man auch einen Dialog nutzen.
Form-Funktionen: Reset und Validate
Die Komponente v-form hat die Funktionen reset(), validate() und resetValidation(), die über eine Referenz (ref) im Script-Code, zum Beispiel als Folge eines Klicks auf einen Button, aufgerufen werden können:
<v-form ref="form">
...
this.$refs.form.validate()
Validate() führt die Validierung durch und gibt das Ergebnis als Boolean zurück. Damit lässt sich also vor dem Abschicken prüfen, ob das Formular gültig ist. Reset() löscht Eingaben und Validierungsfehler, resetValidation() dagegen nur die Validierungsfehler.
Das fertige Formular ist in der vorangestellten Abbildung zu sehen. Vuetify beinhaltet eine Menge weiterer Komponenten, die hervorragende Dokumentation listet dazu zahlreiche Beispiele auf.
(ID:48371616)