Benutzerdefinierte Ereignisse
Auf dieser Seite wird davon ausgegangen, dass Sie Komponentengrundlagen gelesen haben. Wenn Sie noch nicht viel über Komponenten wissen, empfehle ich Ihnen, es zuerst zu lesen.
Inhaltsverzeichnis
Ereignisname
ist unterschiedlich Für Komponenten und Requisiten gibt es keine automatische Groß-/Kleinschreibung für Ereignisnamen. Stattdessen muss der Name des ausgelösten Ereignisses genau mit dem Namen übereinstimmen, der zum Abhören dieses Ereignisses verwendet wird. Wenn beispielsweise ein Ereignis mit einem CamelCase-Namen ausgelöst wird:
this.$emit('myEvent')
, hat das Anhören der Kebab-Case-Version dieses Namens keine Auswirkung:
<!-- 没有效果 --> <my-component v-on:my-event="doSomething"></my-component>
Im Gegensatz zu Komponenten und Requisiten, Ereignissen Der Name wird nicht als JavaScript-Variable oder Eigenschaftsname verwendet, daher gibt es keinen Grund, camelCase oder PascalCase zu verwenden. Und der v-on
-Ereignis-Listener wird in der DOM-Vorlage automatisch in Kleinbuchstaben konvertiert (da bei HTML die Groß-/Kleinschreibung nicht beachtet wird), sodass v-on:myEvent
zu v-on:myevent
wird – was es unmöglich macht, dass myEvent
überwacht ankommt.
Daher empfehlen wir Ihnen immer kebab-case
Ereignisnamen zu verwenden.
Benutzerdefinierte Komponente v-model
2.2.0 Hinzugefügt
Das v-model
einer Komponente verwendet standardmäßig den Namen value
prop und benannt input
Ereignisse, aber Eingabesteuerelemente wie Optionsfelder, Kontrollkästchen usw. können das value
-Attribut für verschiedene Zwecke verwenden. Die Option model
kann verwendet werden, um solche Konflikte zu vermeiden:
Vue.component('base-checkbox', { model: { prop: 'checked', event: 'change' }, props: { checked: Boolean }, template: ` <input type="checkbox" v-bind:checked="checked" v-on:change="$emit('change', $event.target.checked)" > ` })
Wenn Sie nun v-model
für diese Komponente verwenden:
<base-checkbox v-model="lovingVue"></base-checkbox>
Der Wert von lovingVue
wird hier an dieses A übergeben Requisite mit dem Namen checked
. Wenn <base-checkbox>
gleichzeitig ein change
-Ereignis mit einem neuen Wert auslöst, werden die Attribute dieses lovingVue
aktualisiert.
Beachten Sie, dass Sie die
props
-Requisite weiterhin in denchecked
-Optionen der Komponente deklarieren müssen.
Native Ereignisse an Komponenten binden
Dieses Mal haben Sie möglicherweise viele Ich möchte ein natives Ereignis direkt im Stammelement einer Komponente abhören. Zu diesem Zeitpunkt können Sie den Modifikator v-on
von .native
verwenden:
<base-input v-on:focus.native="onFocus"></base-input>
Das kann manchmal nützlich sein, ist aber keine gute Idee, wenn Sie versuchen, auf ein ganz bestimmtes Element wie <input>
zu achten. Beispielsweise wurde die obige <base-input>
-Komponente möglicherweise wie folgt umgestaltet, sodass das Stammelement tatsächlich ein <label>
-Element ist:
<label> {{ label }} <input v-bind="$attrs" v-bind:value="value" v-on:input="$emit('input', $event.target.value)" > </label>
Zu diesem Zeitpunkt schlägt der .native
-Listener des übergeordneten Elements stillschweigend fehl. Es werden keine Fehler generiert, aber der onFocus
-Handler wird nicht wie erwartet aufgerufen.
Um dieses Problem zu lösen, stellt Vue ein $listeners
-Attribut bereit, bei dem es sich um ein Objekt handelt, das alle Listener enthält, die auf diese Komponente agieren. Beispiel:
{ focus: function (event) { /* ... */ } input: function (value) { /* ... */ }, }
Mit diesem $listeners
-Attribut können Sie v-on="$listeners"
verwenden, um alle Ereignis-Listener auf ein bestimmtes untergeordnetes Element dieser Komponente zu verweisen. Für Komponenten wie <input>
, mit denen Sie auch v-model
arbeiten möchten, ist es oft nützlich, eine berechnete Eigenschaft für diese Listener wie die folgende zu erstellen inputListeners
:
Vue.component('base-input', { inheritAttrs: false, props: ['label', 'value'], computed: { inputListeners: function () { var vm = this // `Object.assign` 将所有的对象合并为一个新对象 return Object.assign({}, // 我们从父级添加所有的监听器 this.$listeners, // 然后我们添加自定义监听器, // 或覆写一些监听器的行为 { // 这里确保组件配合 `v-model` 的工作 input: function (event) { vm.$emit('input', event.target.value) } } ) } }, template: ` <label> {{ label }} <input v-bind="$attrs" v-bind:value="value" v-on="inputListeners" > </label> ` })
Jetzt ist die <base-input>
-Komponente vorhanden eine völlig transparente Hülle, was bedeutet, dass sie sich genau wie eine gewöhnliche <input>
verhalten kann Das Element wird auf die gleiche Weise verwendet: Es funktionieren dieselben Eigenschaften und Listener.
.sync
.sync
Modifikatoren .sync
.sync2.3.0 Neu hinzugefügt
update:myPropName
In einigen Fällen müssen wir möglicherweise eine Requisite „in beide Richtungen binden“. Sicherlich". Leider führt eine echte bidirektionale Bindung zu Wartungsproblemen, da untergeordnete Komponenten ihre übergeordneten Komponenten ändern können, ohne dass eine offensichtliche Änderungsquelle für die übergeordneten oder untergeordneten Komponenten vorliegt. title
-Modus zum Auslösen von Ereignissen zu verwenden. Beispielsweise können wir in einer hypothetischen Komponente, die eine
-Requisite enthält, die Absicht ausdrücken, ihr einen neuen Wert zuzuweisen mit:this.$emit('update:title', newTitle)
.sync
Dann kann die übergeordnete Komponente dieses Ereignis abhören und bei Bedarf aktualisieren Lokale Datenattribute. Zum Beispiel: <text-document v-bind:title="doc.title" v-on:update:title="doc.title = $event" ></text-document>
Der Einfachheit halber stellen wir für dieses Muster eine Abkürzung bereit, nämlich.Modifikatoren:
.sync
<text-document v-bind:title.sync="doc.title"></text-document>v-bind
Beachten Sie, dassv-bind:title.sync=”doc.title ‘!’
mit dem Modifikatorv-model
nicht zusammen mit und Ausdrücken (z. B. <🎜) verwendet werden kann >" ist ungültig. Stattdessen können Sie nur den Eigenschaftsnamen angeben, den Sie binden möchten, ähnlich wie
.sync
v-bind
Wenn wir ein Objekt verwenden, um mehrere festzulegen prop, Sie können diesen
<text-document v-bind.sync="doc"></text-document>
Dadurch wird jedes Attribut (z. B. Titel) im Dokumentobjekt als unabhängige Requisite übergeben und dann V-On-Listener für Aktualisierungen hinzugefügt.
Die Verwendung von
v-bind.sync
für ein Literalobjekt wiev-bind.sync=”{ title: doc.title }”
funktioniert nicht ordnungsgemäß, da beim Parsen eines komplexen Ausdrucks wie diesem viele Randfälle berücksichtigt werden müssen.