Hinzufügen eines neuen Todo-Formulars: Vue-Events, Methoden und Modelle
Hinweis: Die MDN Vue-Artikel werden nicht mehr gepflegt und werden in 3 Monaten (bis zum 20. August 2026) von der Website entfernt. Der Inhalt wird im MDN Museum archiviert. Weitere Informationen finden Sie in dieser Diskussion.
Wir haben nun Beispieldaten und eine Schleife, die jedes Datenstück nimmt und es innerhalb eines ToDoItem in unserer App rendert. Was wir als nächstes wirklich brauchen, ist die Möglichkeit, unseren Nutzern das Eingeben ihrer eigenen Todo-Elemente in die App zu ermöglichen. Dazu benötigen wir ein Text-<input>, ein Ereignis, das ausgelöst wird, wenn die Daten übermittelt werden, eine Methode, die bei der Übermittlung ausgelöst wird, um die Daten hinzuzufügen und die Liste neu zu rendern, sowie ein Modell zur Steuerung der Daten. Dies werden wir in diesem Artikel behandeln.
| Voraussetzungen: |
Vertrautheit mit den Kernsprachen HTML, CSS und JavaScript, Kenntnisse des Terminals/Befehlszeile. Vue-Komponenten werden als Kombination aus JavaScript-Objekten geschrieben, die die Daten der App verwalten, und einer HTML-basierten Vorlagensyntax, die der zugrunde liegenden DOM-Struktur zugeordnet ist. Für die Installation und die Nutzung einiger der fortgeschritteneren Funktionen von Vue (wie Single File Components oder Rendermethoden) benötigen Sie ein Terminal mit installierten node + npm. |
|---|---|
| Ziel: | Erlernen der Formularbearbeitung in Vue und damit verbunden der Ereignisse, Modelle und Methoden. |
Ein neues To-Do-Formular erstellen
Wir haben jetzt eine App, die eine Liste von To-Do-Elementen anzeigt. Allerdings können wir unsere Liste von Elementen nicht aktualisieren, ohne unseren Code manuell zu ändern! Lassen Sie uns das beheben. Lassen Sie uns eine neue Komponente erstellen, die es uns ermöglicht, ein neues To-Do-Element hinzuzufügen.
-
Erstellen Sie in Ihrem Komponentenordner eine neue Datei namens
ToDoForm.vue. -
Fügen Sie wie zuvor ein leeres
<template>und ein<script>-Tag hinzu:vue<template></template> <script> export default {}; </script> -
Fügen Sie ein HTML-Formular hinzu, das es ermöglicht, ein neues Todo-Element einzugeben und es in die App zu übermitteln. Wir benötigen ein
<form>mit einem<label>, einem<input>und einem<button>. Aktualisieren Sie Ihre Vorlage wie folgt:vue<template> <form> <label for="new-todo-input"> What needs to be done? </label> <input type="text" id="new-todo-input" name="new-todo" autocomplete="off" /> <button type="submit">Add</button> </form> </template>Wir haben jetzt eine Formularkomponente, in die wir den Titel eines neuen Todo-Elements eingeben können (die beim Rendern zum Label des entsprechenden
ToDoItemwird). -
Laden Sie diese Komponente in unsere App. Gehen Sie zurück zu
App.vueund fügen Sie die folgendeimport-Anweisung direkt unter der vorherigen innerhalb Ihres<script>-Elements hinzu:jsimport ToDoForm from "./components/ToDoForm.vue"; -
Registrieren Sie die neue Komponente in Ihrer
App-Komponente — aktualisieren Sie diecomponents-Eigenschaft des Komponentenobjekts, damit es so aussieht:jsexport default { // … components: { ToDoItem, ToDoForm, }, // … }; -
Rendern Sie abschließend für diesen Abschnitt Ihre
ToDoForm-Komponente in Ihrer App, indem Sie das<to-do-form />-Element innerhalb Ihres<template>-Elements derAppwie folgt hinzufügen:vue<template> <div id="app"> <h1>My To-Do List</h1> <to-do-form></to-do-form> <ul> <li v-for="item in ToDoItems" :key="item.id"> <to-do-item :label="item.label" :done="item.done" :id="item.id"></to-do-item> </li> </ul> </div> </template>
Wenn Sie nun Ihre laufende Seite ansehen, sollten Sie das neue Formular angezeigt sehen.

Wenn Sie es ausfüllen und auf die Schaltfläche "Add" klicken, postet die Seite das Formular zurück an den Server, aber das ist nicht wirklich das, was wir wollen. Was wir eigentlich wollen, ist, eine Methode beim submit-Ereignis auszuführen, die das neue Todo-Element zur ToDoItem-Datenliste in App hinzufügt. Dazu müssen wir der Komponenteninstanz eine Methode hinzufügen.
Eine Methode erstellen und mit v-on an ein Ereignis binden
Um eine Methode in der ToDoForm-Komponente verfügbar zu machen, müssen wir sie dem Komponentenobjekt hinzufügen, und dies geschieht innerhalb einer methods-Eigenschaft unserer Komponente, die an der gleichen Stelle wie data(), props usw. steht. Die methods-Eigenschaft enthält alle Methoden, die wir möglicherweise in unserer Komponente aufrufen müssen. Wenn auf sie verwiesen wird, werden Methoden vollständig ausgeführt, daher ist es keine gute Idee, sie zur Anzeige von Informationen innerhalb der Vorlage zu verwenden. Um Daten anzuzeigen, die aus Berechnungen stammen, sollten Sie eine computed-Eigenschaft verwenden, die wir später behandeln werden.
-
In dieser Komponente müssen wir eine
onSubmit()-Methode zurmethods-Eigenschaft innerhalb desToDoForm-Komponentenobjekts hinzufügen. Wir verwenden diese, um die Übermittlungsaktion zu handhaben.Fügen Sie dies wie folgt hinzu:
jsexport default { methods: { onSubmit() { console.log("form submitted"); }, }, }; -
Als Nächstes müssen wir die Methode an den
submit-Ereignishandler des<form>-Elements binden. Ähnlich wie Vue diev-bind-Syntax für das Binden von Attributen verwendet, hat Vue eine spezielle Direktive für die Ereignisbehandlung:v-on. Diev-on-Direktive funktioniert mit derv-on:event="method"-Syntax. Und ähnlich wie beiv-bindgibt es auch eine Kurzsyntax:@event="method".Wir verwenden hier die Kurzsyntax zur Konsistenz. Fügen Sie den
submit-Handler wie folgt zu Ihrem<form>-Element hinzu:vue<form @submit="onSubmit">…</form> -
Wenn Sie dies ausführen, postet die App die Daten immer noch zum Server, was einen Refresh verursacht. Da wir unsere gesamte Verarbeitung auf dem Client durchführen, gibt es keinen Server, um die Rücksendung zu verarbeiten. Wir verlieren auch den gesamten lokalen Zustand bei Seitenaktualisierung. Um zu verhindern, dass der Browser an den Server postet, müssen wir die Standardaktion des Ereignisses stoppen, während es durch die Seite blubbert (
Event.preventDefault()in Vanilla JavaScript). Vue hat eine spezielle Syntax namens Ereignismodifikatoren, die dies direkt in unserer Vorlage für uns übernehmen kann.Modifikatoren werden am Ende eines Ereignisses mit einem Punkt angehängt, zum Beispiel:
@event.modifier. Hier ist eine Liste von Ereignismodifikatoren:.stop: Stoppt die Weitergabe des Ereignisses. EntsprichtEvent.stopPropagation()bei regulären JavaScript-Ereignissen..prevent: Verhindert das Standardverhalten des Ereignisses. EntsprichtEvent.preventDefault()..self: Löst den Handler nur aus, wenn das Ereignis genau von diesem Element ausgelöst wurde.{.key}: Löst den Ereignishandler nur über die angegebene Taste aus. MDN hat eine Liste gültiger Schlüsselwerte; mehrwortige Tasten müssen einfach in kebab-case umgewandelt werden (z.B.,page-down)..native: Lauscht auf ein natales Ereignis auf dem Root-Element (äußerstes Wrapper-Element) Ihrer Komponente..once: Lauscht auf das Ereignis, bis es einmal ausgelöst wurde, und dann nicht mehr..left: Löst den Handler nur bei einem linken Maustastenklickereignis aus..right: Löst den Handler nur bei einem rechten Maustastenklickereignis aus..middle: Löst den Handler nur bei einem mittleren Maustastenklickereignis aus..passive: Entspricht der Verwendung des Parameters{ passive: true }, wenn ein Ereignislistener in Vanilla JavaScript mitaddEventListener()erstellt wird.
In diesem Fall müssen wir den
.prevent-Modifikator verwenden, um die Standard-Einreichungsaktion des Browsers zu stoppen. Fügen Sie.preventwie folgt zum@submit-Handler in Ihrer Vorlage hinzu:vue<form @submit.prevent="onSubmit">…</form>
Wenn Sie nun versuchen, das Formular abzusenden, werden Sie feststellen, dass die Seite nicht neu lädt. Wenn Sie die Konsole öffnen, können Sie die Ergebnisse des console.log() sehen, die wir in unserer onSubmit()-Methode hinzugefügt haben.
Daten mit v-model an Eingaben binden
Als nächstes benötigen wir eine Möglichkeit, den Wert aus dem <input> des Formulars zu erhalten, damit wir das neue Todo-Element zu unserer ToDoItems-Datenliste hinzufügen können.
Das erste, was wir benötigen, ist eine data-Eigenschaft in unserem Formular, um den Wert des Todos zu verfolgen.
-
Fügen Sie eine
data()-Methode zu unseremToDoForm-Komponentenobjekt hinzu, die einlabel-Feld zurückgibt. Wir können den anfänglichen Wert deslabelauf eine leere Zeichenfolge setzen.Ihr Komponentenobjekt sollte jetzt in etwa so aussehen:
jsexport default { methods: { onSubmit() { console.log("form submitted"); }, }, data() { return { label: "", }; }, }; -
Wir benötigen nun eine Möglichkeit, den Wert des
new-todo-input-Felds an daslabel-Feld anzukoppeln. Vue hat dafür eine spezielle Direktive:v-model.v-modelbindet an die von Ihnen festgelegte Daten-Eigenschaft und hält sie mit dem<input>synchron.v-modelfunktioniert bei allen verschiedenen Eingabetypen, einschließlich Checkboxes, Radios und Select-Eingaben. Umv-modelzu verwenden, fügen Sie dem<input>ein Attribut mit der Strukturv-model="variable"hinzu.In unserem Fall würden wir es zu unserem
new-todo-input-Feld wie unten gezeigt hinzufügen. Tun Sie dies jetzt:vue<input type="text" id="new-todo-input" name="new-todo" autocomplete="off" v-model="label" />Hinweis: Sie können
<input>-Werte auch mithilfe einer Kombination aus Ereignissen undv-bind-Attributen synchronisieren. Tatsächlich machtv-modelgenau das im Hintergrund. Allerdings variieren die genaue Ereignis- und Attributkombination je nach Eingabetypen und erfordert mehr Code als nur die Verwendung derv-model-Verknüpfung. -
Testen wir unsere Verwendung von
v-model, indem wir den Wert der in unsereronSubmit()-Methode übermittelten Daten protokollieren. In Komponenten werden Datenattribute mit dem Schlüsselwortthisaufgerufen. Also greifen wir auf unserlabel-Feld mitthis.labelzu.Aktualisieren Sie Ihre
onSubmit()-Methode, damit sie so aussieht:jsexport default { methods: { onSubmit() { console.log("Label value: ", this.label); }, }, }; -
Gehen Sie jetzt zurück zu Ihrer laufenden App, fügen Sie etwas Text in das
<input>-Feld ein und klicken Sie auf die Schaltfläche "Add". Sie sollten sehen, dass der eingegebene Wert in der Konsole protokolliert wird, zum Beispiel:Label value: My value
V-Model-Verhalten mit Modifikatoren ändern
In ähnlicher Weise wie bei Ereignismodifikatoren können wir auch Modifikatoren hinzufügen, um das Verhalten von v-model zu ändern. In unserem Fall gibt es zwei Modifikatoren, die wir in Betracht ziehen sollten. Der erste, .trim, entfernt Leerzeichen vor und nach der Eingabe. Wir können den Modifikator der v-model-Anweisung wie folgt hinzufügen: v-model.trim="label".
Der zweite Modifikator, den wir in Betracht ziehen sollten, ist .lazy. Dieser Modifikator ändert, wann v-model den Wert für Texteingaben synchronisiert. Wie bereits erwähnt, synchronisiert v-model Daten durch Aktualisierung der Variablen mithilfe von Ereignissen. Bei Texteingaben erfolgt diese Synchronisierung mit dem input-Ereignis. Oft bedeutet dies, dass Vue die Daten nach jedem Tastendruck synchronisiert. Der .lazy-Modifikator bewirkt, dass v-model stattdessen das change-Ereignis verwendet. Das bedeutet, dass Vue Daten nur synchronisiert, wenn die Eingabe den Fokus verliert oder das Formular übermittelt wird. Für unsere Zwecke ist dies viel vernünftiger, da wir nur die endgültigen Daten benötigen.
Um sowohl den .lazy-Modifikator als auch den .trim-Modifikator zusammen zu verwenden, können wir sie verkettet angeben, zum Beispiel: v-model.lazy.trim="label".
Aktualisieren Sie Ihr v-model-Attribut, um lazy und trim wie oben gezeigt zu verketten, und testen Sie dann Ihre App erneut. Versuchen Sie zum Beispiel, einen Wert mit Leerzeichen an beiden Enden einzugeben.
Daten an Elternkomponenten mit benutzerdefinierten Ereignissen übergeben
Wir sind nun sehr nah dran, neue To-Do-Elemente zu unserer Liste hinzufügen zu können. Das nächste, was wir tun müssen, ist, das neu erstellte To-Do-Element an unsere App-Komponente zu übergeben. Dazu kann unsere ToDoForm ein benutzerdefiniertes Ereignis auslösen, das die Daten übergibt, und App kann darauf hören. Dies funktioniert sehr ähnlich wie native Ereignisse auf HTML-Elementen: Eine Kindkomponente kann ein Ereignis auslösen, das über v-on abgehört werden kann.
Im onSubmit-Ereignishandler unserer ToDoForm fügen wir ein todo-added-Ereignis hinzu. Benutzerdefinierte Ereignisse werden so ausgelöst: this.$emit("event-name"). Es ist wichtig zu wissen, dass Ereignishandler case-sensitiv sind und keine Leerzeichen enthalten können. Vue-Vorlagen werden auch in Kleinbuchstaben umgewandelt, was bedeutet, dass Vue-Vorlagen nicht auf Ereignisse hören können, die mit Großbuchstaben benannt sind.
-
Ersetzen Sie das
console.log()in deronSubmit()-Methode durch folgendes:jsthis.$emit("todo-added"); -
Gehen Sie als nächstes zurück zu
App.vueund fügen Sie Ihrer Komponenten-Objekteigenschaft einemethods-Eigenschaft hinzu, die eineaddToDo()-Methode enthält, wie unten gezeigt. Diese Methode kann vorerst einfachTo-do addedin die Konsole loggen.jsexport default { name: "app", components: { ToDoItem, ToDoForm, }, data() { return { ToDoItems: [ { id: `todo-${nanoid()}`, label: "Learn Vue", done: false }, { id: `todo-${nanoid()}`, label: "Create a Vue project with the CLI", done: true, }, { id: `todo-${nanoid()}`, label: "Have fun", done: true }, { id: `todo-${nanoid()}`, label: "Create a to-do list", done: false, }, ], }; }, methods: { addToDo() { console.log("To-do added"); }, }, }; -
Fügen Sie als nächstes einen Ereignis-Listener für das
todo-added-Ereignis zur<to-do-form></to-do-form>hinzu, der dieaddToDo()-Methode aufruft, wenn das Ereignis ausgelöst wird. Mit der@-Kurzsyntax sieht der Listener so aus:@todo-added="addToDo":vue<to-do-form @todo-added="addToDo"></to-do-form> -
Wenn Sie Ihr
ToDoFormübermitteln, sollten Sie die Konsolenprotokollierung von deraddToDo()-Methode sehen. Das ist gut, aber wir übergeben noch keine Daten zurück an dieApp.vue-Komponente. Das können wir erreichen, indem wir zusätzliche Argumente zurthis.$emit()-Funktion zurück in derToDoForm-Komponente übergeben.In diesem Fall, wenn wir das Ereignis auslösen, wollen wir die
label-Daten zusammen mit übergeben. Dies kann durch das Übergeben der Daten, die Sie übergeben möchten, als weiteren Parameter in der$emit()-Methode geschehen:this.$emit("todo-added", this.label). Dies ähnelt der Art und Weise, wie native JavaScript-Ereignisse Daten enthalten, außer dass benutzerdefinierte Vue-Ereignisse kein Ereignisobjekt standardmäßig enthalten. Dies bedeutet, dass das emittierte Ereignis direkt dem Objekt entspricht, das Sie übergeben. In unserem Fall wird unser Ereignisobjekt also nur eine Zeichenfolge sein.Aktualisieren Sie Ihre
onSubmit()-Methode wie folgt:jsexport default { // … methods: { // … onSubmit() { this.$emit("todo-added", this.label); }, // … }, // … }; -
Um diese Daten tatsächlich in
App.vueabzurufen, müssen wir unsereraddToDo()-Methode ein Parameter hinzufügen, das daslabeldes neuen To-Do-Elements beinhaltet.Gehen Sie zurück zu
App.vueund aktualisieren Sie dies jetzt:jsexport default { // … methods: { // … addToDo(toDoLabel) { console.log("To-do added:", toDoLabel); }, // … }, // … };
Wenn Sie Ihr Formular erneut testen, werden Sie sehen, dass der eingegebene Text bei der Übermittlung in Ihrer Konsole protokolliert wird. Vue übergibt automatisch die Argumente nach dem Ereignisnamen in this.$emit() an Ihren Ereignishandler.
Das neue Todo zu unseren Daten hinzufügen
Da wir die Daten von ToDoForm in App.vue verfügbar haben, müssen wir ein Element, das es darstellt, dem ToDoItems-Array hinzufügen. Dies kann durch das Hinzufügen eines neuen To-Do-Objekts zum Array geschehen, das unsere neuen Daten enthält.
-
Aktualisieren Sie Ihre
addToDo()-Methode wie folgt:jsexport default { // … methods: { // … addToDo(toDoLabel) { this.ToDoItems.push({ id: `todo-${nanoid()}`, label: toDoLabel, done: false, }); }, // … }, // … }; -
Versuchen Sie, Ihr Formular erneut zu testen, und Sie sollten sehen, dass neue To-Do-Elemente am Ende der Liste angehängt werden.
-
Lassen Sie uns noch eine weitere Verbesserung vornehmen, bevor wir fortfahren. Wenn Sie das Formular absenden, während das Eingabefeld leer ist, werden To-Do-Elemente ohne Text immer noch zur Liste hinzugefügt. Um das zu beheben, können wir verhindern, dass das
todo-added-Ereignis ausgelöst wird, wenn der Name leer ist. Da der Name bereits durch den.trim-Modifikator getrimmt wird, müssen wir nur auf die leere Zeichenfolge testen.Gehen Sie zurück zu Ihrer
ToDoForm-Komponente und aktualisieren Sie dieonSubmit()-Methode wie folgt. Wenn derlabel-Wert leer ist, lassen Sie uns dastodo-added-Ereignis nicht auslösen.jsexport default { // … methods: { // … onSubmit() { if (this.label === "") { return; } this.$emit("todo-added", this.label); }, // … }, // … }; -
Versuchen Sie erneut Ihr Formular. Jetzt können Sie keine leeren Elemente mehr zur To-Do-Liste hinzufügen.

Verwendung von v-model zum Aktualisieren eines Eingabewerts
Es gibt noch eine Sache zu fixieren in unserer ToDoForm-Komponente — nach dem Absenden enthält das <input>-Feld immer noch den alten Wert. Aber dies ist leicht zu beheben — da wir v-model verwenden, um die Daten an das <input> in ToDoForm zu binden, wird das Eingabefeld ebenfalls aktualisiert, wenn wir den name-Parameter auf eine leere Zeichenfolge setzen.
Aktualisieren Sie die onSubmit()-Methode Ihrer ToDoForm-Komponente zu diesem:
export default {
// …
methods: {
// …
onSubmit() {
if (this.label === "") {
return;
}
this.$emit("todo-added", this.label);
this.label = "";
},
// …
},
// …
};
Nun wird beim Klicken auf die Schaltfläche "Add" das "new-todo-input" selbst geleert.
Zusammenfassung
Ausgezeichnet. Wir können nun Todo-Elemente zu unserem Formular hinzufügen! Unsere App beginnt sich nun interaktiv anzufühlen, aber ein Problem ist, dass wir das Aussehen und Feeling bisher völlig ignoriert haben. Im nächsten Artikel konzentrieren wir uns darauf, dies zu beheben und die verschiedenen Möglichkeiten anzusehen, die Vue zum Styling von Komponenten bietet.