Komponentengrundlagen
Inhaltsverzeichnis
übergeben werden Stütze Übergabe von Daten an untergeordnete Komponenten
Analyse Was Sie bei der Verwendung von DOM-Vorlagen beachten sollten
Grundlegendes Beispiel
Hier gibt es einen Vue Beispiel einer Komponente:
// 定义一个名为 button-counter 的新组件 Vue.component('button-counter', { data: function () { return { count: 0 } }, template: '<button v-on:click="count++">You clicked me {{ count }} times.</button>' })
Eine Komponente ist eine wiederverwendbare Vue-Instanz mit einem Namen: in diesem Fall <button-counter>
. Wir können diese Komponente als benutzerdefiniertes Element in einer Vue-Stamminstanz verwenden, die von new Vue
erstellt wurde:
<div id="components-demo"> <button-counter></button-counter> </div>
new Vue({ el: '#components-demo' })
, da die Komponente wiederverwendbares Vue ist Beispiel, sodass sie dieselben Optionen wie new Vue
erhalten, z. B. data
, computed
, watch
, methods
und Lebenszyklus-Hooks usw. Die einzigen Ausnahmen sind Root-Instanz-spezifische Optionen wie el
.
Wiederverwendung von Komponenten
Sie können Komponenten beliebig oft wiederverwenden Wiederverwendung:
<div id="components-demo"> <button-counter></button-counter> <button-counter></button-counter> <button-counter></button-counter> </div>
Beachten Sie, dass beim Klicken auf eine Schaltfläche jede Komponente ihre count
unabhängig beibehält. Denn jedes Mal, wenn Sie eine Komponente verwenden, wird eine neue Instanz davon erstellt.
data
data
<button-counter>
data
data: { count: 0 }
Stattdessen die data
-Option einer Komponente muss eine Funktion sein, damit jede Instanz eine separate Kopie des zurückgegebenen Objekts verwalten kann:
data: function () { return { count: 0 } }
if Vue Ohne diese Regel kann sich das Klicken auf eine Schaltfläche auf alle anderen Instanzen wie den folgenden Code auswirken:
Organisation von Komponenten
Normalerweise Eine Anwendung wird in Form eines verschachtelten Komponentenbaums organisiert:
Sie können beispielsweise eine Kopfzeile, eine Seitenleiste, einen Inhaltsbereich usw. haben. Komponenten, Jede Komponente enthält andere Komponenten wie Navigationslinks und Blogbeiträge.
Um in Vorlagen verwendet zu werden, müssen diese Komponenten zunächst registriert werden, damit Vue sie erkennen kann. Es gibt zwei Arten der Komponentenregistrierung: globale Registrierung und lokale Registrierung. Bisher wurden unsere Komponenten nur über Vue.component
global registriert:
Vue.component('my-component-name', { // ... options ... })
Global registrierte Komponenten können nach der Registrierung in jeder neu erstellten Vue-Root-Instanz (über new Vue
) verwendet werden, auch in der Vorlage aller untergeordneten Komponenten in seinem Komponentenbaum.
Das ist bisher alles, was Sie über die Komponentenregistrierung wissen müssen. Wenn Sie diese Seite zu Ende gelesen haben und deren Inhalt beherrschen, empfehlen wir Ihnen, noch einmal vorbeizukommen und die Komponente zu registrieren.
Übergabe von Daten an untergeordnete Komponenten über Props
Zuvor haben wir das Erstellen eines Blogs erwähnt Post-Komponente. Das Problem besteht darin, dass die Daten, die wir anzeigen möchten, z. B. der Titel oder der Inhalt eines Blog-Beitrags, nicht an diese Komponente übergeben werden können. Hierher kommen Requisiten.
Requisiten sind einige benutzerdefinierte Eigenschaften, die Sie für die Komponente registrieren können. Wenn ein Wert an ein Prop-Attribut übergeben wird, wird er zu einer Eigenschaft dieser Komponenteninstanz. Um einen Titel an die Blog-Komponente zu übergeben, können wir eine props
-Option verwenden, um ihn in die Liste der von der Komponente akzeptierten Requisiten aufzunehmen:
Vue.component('blog-post', { props: ['title'], template: '<h3>{{ title }}</h3>' })
Eine Komponente kann standardmäßig eine beliebige Anzahl von Requisiten haben. und jeder Wert ist akzeptabel. Wird an jede Requisite übergeben. In der obigen Vorlage werden Sie feststellen, dass wir auf diesen Wert in der Komponenteninstanz zugreifen können, genau wie auf den Wert in Daten.
Nachdem eine Requisite registriert wurde, können Sie die Daten als benutzerdefiniertes Merkmal wie folgt übergeben:
<blog-post title="My journey with Vue"></blog-post> <blog-post title="Blogging with Vue"></blog-post> <blog-post title="Why Vue is so fun"></blog-post>
In einer typischen Anwendung ist dies jedoch möglich in data
sein Es gibt eine Reihe von Blog-Beiträgen:
new Vue({ el: '#blog-post-demo', data: { posts: [ { id: 1, title: 'My journey with Vue' }, { id: 2, title: 'Blogging with Vue' }, { id: 3, title: 'Why Vue is so fun' } ] } })
und ich möchte für jeden Blog-Beitrag eine Komponente rendern:
<blog-post v-for="post in posts" v-bind:key="post.id" v-bind:title="post.title" ></blog-post>
Wie oben gezeigt, werden Sie feststellen, dass wir v-bind
verwenden können, um Requisiten dynamisch weiterzugeben. Dies ist sehr nützlich, wenn Sie den spezifischen Inhalt, der zu Beginn gerendert werden soll, nicht kennen, z. B. wenn Sie eine Liste von Blogbeiträgen von einer API abrufen möchten.
Das ist bisher alles, was Sie über Prop wissen müssen. Wenn Sie diese Seite zu Ende gelesen haben und ihren Inhalt beherrschen, empfehlen wir Ihnen, noch einmal vorbeizuschauen und Prop noch einmal durchzulesen.
Ein einzelnes Wurzelelement
Beim Erstellen eines <blog-post>
Komponente enthält Ihre Vorlage am Ende viel mehr als nur einen Titel:
<h3>{{ title }}</h3>
Zumindest werden Sie den Textkörper des Blog-Beitrags einfügen:
<h3>{{ title }}</h3> <div v-html="content"></div>
Wenn Sie jedoch Versuchen Sie, dies in die Vorlage zu schreiben. Vue zeigt einen Fehler an und erklärt, dass jede Komponente ein einzelnes Stammelement haben muss (Jede Komponente darf nur ein Wurzelelement haben) . Sie können dieses Problem beheben, indem Sie den Inhalt der Vorlage in ein übergeordnetes Element einschließen, zum Beispiel:
<div class="blog-post"> <h3>{{ title }}</h3> <div v-html="content"></div> </div>
Da die Komponenten immer komplexer werden, benötigen unsere Blog-Beiträge anscheinend nicht nur Titel und Inhalte, sondern auch Erfordert Veröffentlichungsdatum, Rezensionen usw. Das Definieren einer Requisite für jede relevante Information kann umständlich werden:
<blog-post v-for="post in posts" v-bind:key="post.id" v-bind:title="post.title" v-bind:content="post.content" v-bind:publishedAt="post.publishedAt" v-bind:comments="post.comments" ></blog-post>
Es ist also an der Zeit, die <blog-post>
-Komponente umzugestalten, um ein einzelnes post
zu akzeptieren prop:
<blog-post v-for="post in posts" v-bind:key="post.id" v-bind:post="post" ></blog-post>
Vue.component('blog-post', { props: ['post'], template: ` <div class="blog-post"> <h3>{{ post.title }}</h3> <div v-html="post.content"></div> </div> ` })
Dieses und einige der folgenden Beispiele verwenden die Vorlagenzeichenfolgen von JavaScript, um mehrzeilige Vorlagen besser lesbar zu machen. Sie werden im IE nicht unterstützt. Wenn Sie also den IE ohne Kompilierung (über Tools wie Babel oder TypeScript) unterstützen müssen, verwenden Sie bitte stattdessen das Breakline-Escape-Zeichen .
Jetzt ist jedes Mal, wenn Sie einem post
-Objekt eine neue Eigenschaft hinzufügen, diese automatisch in <blog-post>
verfügbar.
Auf Ereignisse der untergeordneten Komponente hören
Wenn wir die Komponente <blog-post>
entwickeln, Bei einigen Funktionen müssen wir möglicherweise mit übergeordneten Komponenten kommunizieren. Beispielsweise könnten wir eine Hilfsfunktion einführen, um die Schriftgröße eines Blog-Beitrags zu erhöhen, während der Rest der Seite die Standardschriftgröße beibehält.
In der übergeordneten Komponente können wir diese Funktion unterstützen, indem wir ein postFontSize
Datenattribut hinzufügen:
new Vue({ el: '#blog-posts-events-demo', data: { posts: [/* ... */], postFontSize: 1 } })
Es kann in der Vorlage verwendet werden, um die Schriftgröße aller Blogs zu steuern Beiträge:
<div id="blog-posts-events-demo"> <div :style="{ fontSize: postFontSize + 'em' }"> <blog-post v-for="post in posts" v-bind:key="post.id" v-bind:post="post" ></blog-post> </div> </div>
Jetzt fügen wir vor jedem Blog-Beitragstext eine Schaltfläche ein, um die Schriftgröße zu vergrößern:
Vue.component('blog-post', { props: ['post'], template: ` <div class="blog-post"> <h3>{{ post.title }}</h3> <button> Enlarge text </button> <div v-html="post.content"></div> </div> ` })
Das Problem ist, dass diese Schaltfläche nichts bewirkt:
<button> Enlarge text </button>
Wenn auf diese Schaltfläche geklickt wird, müssen wir die übergeordnete Komponente anweisen, den Text aller Blogbeiträge zu vergrößern. Glücklicherweise bieten Vue-Instanzen ein benutzerdefiniertes Ereignissystem, um dieses Problem zu lösen. Die übergeordnete Komponente kann jedes Ereignis der untergeordneten Komponenteninstanz über v-on
abhören, genau wie die Verarbeitung nativer DOM-Ereignisse:
<blog-post ... v-on:enlarge-text="postFontSize += 0.1" ></blog-post>
Gleichzeitig kann die untergeordnete Komponente das integrierte <🎜 aufrufen > Methode $emit
und übergeben Geben Sie den Ereignisnamen ein, um ein Ereignis auszulösen:
<button v-on:click="$emit('enlarge-text')"> Enlarge text </button>Mit diesem
Listener, die übergeordnete Komponente empfängt das Ereignis und aktualisiert den Wert von v-on:enlarge-text="postFontSize = 0.1"
. postFontSize
Verwenden Sie ein Ereignis, um einen Wert auszulösen
Ja Es ist nützlich, ein Ereignis zu verwenden, um einen bestimmten Wert auszulösen. Beispielsweise möchten wir möglicherweise, dass die-Komponente entscheidet, um wie viel ihr Text vergrößert werden soll. Zu diesem Zeitpunkt können Sie den zweiten Parameter von <blog-post>
verwenden, um diesen Wert bereitzustellen: $emit
<button v-on:click="$emit('enlarge-text', 0.1)"> Enlarge text </button>Wenn wir dann dieses Ereignis in der übergeordneten Komponente abhören, können wir
übergeben Greifen Sie auf den ausgelösten Wert zu: $event
<blog-post ... v-on:enlarge-text="postFontSize += $event" ></blog-post>Oder, wenn der Ereignishandler eine Methode ist:
<blog-post ... v-on:enlarge-text="onEnlargeText" ></blog-post>, dann wird der Wert als erster Parameter an die Methode übergeben:
methods: { onEnlargeText: function (enlargeAmount) { this.postFontSize += enlargeAmount } }
wird für Komponenten verwendet v-model
unterstützen. Denken Sie daran: v-model
<input v-model="searchText">entspricht:
<input v-bind:value="searchText" v-on:input="searchText = $event.target.value" >Bei Verwendung auf einer Komponente sieht
folgendermaßen aus: v-model
<custom-input v-bind:value="searchText" v-on:input="searchText = $event" ></custom-input>Damit es ordnungsgemäß funktioniert, muss diese Komponente The
drin muss: <input>
- Das
-Attribut ist an eine Requisite namens
value
gebunden undvalue
- übergibt den neuen Wert durch das benutzerdefinierte
, wenn sein
input
-Ereignis ausgelöst wird. Das Ereignis löstinput
Vue.component('custom-input', { props: ['value'], template: ` <input v-bind:value="value" v-on:input="$emit('input', $event.target.value)" > ` })Jetzt
Es sollte auf dieser Komponente perfekt funktionieren: v-model
<custom-input v-model="searchText"></custom-input>Das ist bisher alles, was Sie über benutzerdefinierte Komponentenereignisse wissen müssen. Wenn Sie diese Seite zu Ende gelesen haben und deren Inhalt beherrschen, empfehlen wir Ihnen, noch einmal vorbeizuschauen und zu lesen
Benutzerdefinierte Ereignisse bis zum Ende.
Inhalte über Slots
und HTML verteilen Wie bei Elementen müssen wir häufig Inhalte an eine Komponente übergeben, etwa so:
<alert-box> Something bad happened. </alert-box>kann etwa so rendern:
Zum Glück macht das benutzerdefinierte <slot>
-Element von Vue dies sehr einfach:
Vue.component('alert-box', { template: ` <div class="demo-alert-box"> <strong>Error!</strong> <slot></slot> </div> ` })
Wie Sie sehen können, fügen wir nur dort Slots hinzu, wo sie benötigt werden. Das war’s – so einfach ist das!
Das ist bisher alles, was Sie über Spielautomaten wissen müssen. Wenn Sie diese Seite zu Ende gelesen haben und ihren Inhalt beherrschen, empfehlen wir Ihnen, noch einmal vorbeizuschauen und mehr über Spielautomaten zu erfahren.
Dynamische Komponenten
Manchmal zwischen verschiedenen Komponenten Dynamisches Umschalten ist sehr nützlich, beispielsweise in einer Benutzeroberfläche mit mehreren Registerkarten:Der oben genannte Inhalt kann übergeben werden Das
-Element von Vue fügt ein spezielles-Attribut hinzu, um Folgendes zu erreichen: <component>
<!-- 组件会在 `currentTabComponent` 改变时改变 --> <component v-bind:is="currentTabComponent"></component>
is
Im obigen Beispiel Kann currentTabComponent
- den Namen einer registrierten Komponente oder
- das Optionsobjekt einer Komponente
- < enthalten 🎜> Sie können den vollständigen Code hier
dieser Version informieren. Das ist bisher alles, was Sie über dynamische Komponenten wissen müssen. Wenn Sie diese Seite zu Ende gelesen haben und den Inhalt beherrschen, empfehlen wir Ihnen, noch einmal vorbeizukommen und sich über dynamische und asynchrone Komponenten< zu informieren 🎜>Lesen Sie es.
Hinweise beim Parsen von DOM-Vorlagen
Einige HTML-Elemente, z. B. ,
,und
, es gibt strenge Einschränkungen, welche Elemente darin erscheinen dürfen. Einige Elemente wie <ul>
, <ol>
und <table>
können nur innerhalb bestimmter anderer Elemente erscheinen. <select>
<li>
Dies führt dazu, dass wir bei der Verwendung dieser eingeschränkten Elemente auf einige Probleme stoßen. Beispiel: <tr>
<table> <blog-post-row></blog-post-row> </table>
<option>
Diese benutzerdefinierte Komponente wird als ungültiger Inhalt nach außen befördert und führt zu Fehlern im endgültigen Rendering-Ergebnis. Glücklicherweise bietet uns dieses spezielle Feature einen Workaround:
<table> <tr is="blog-post-row"></tr> </table>
Es ist zu beachten, dass <blog-post-row>
diese Einschränkung nicht besteht, wenn wir Vorlagen aus den folgenden Quellen verwendenis
Zeichenfolge (Beispiel: )
Hier müssen Sie über das Parsen von DOM Bescheid wissen Dinge, die Sie bei der Vorlagenerstellung beachten sollten – eigentlich alle notwendigen Inhalte für Vue, das ist alles. Glückwunsch! Als nächstes gibt es noch viel zu lernen, aber wir empfehlen Ihnen zunächst, eine Pause einzulegen, Vue auszuprobieren und selbst zufällige lustige Dinge zu machen.
Wenn Sie das Gefühl haben, dieses Wissen zu beherrschen, empfehlen wir Ihnen, noch einmal alle Seiten des vollständigen Komponentenhandbuchs zu lesen, einschließlich des ausführlichen Komponentenkapitels in der Seitenleiste.