Vue.js für Anfänger Lektion 7: berechnete Eigenschaften
→ Vue.js für Anfänger Lektion 8: Komponenten
Der Zweck der Lektion
Das Hauptziel dieser Lektion ist es, unsere erste Komponente zu erstellen und die Mechanismen zum Übergeben von Daten an Komponenten zu untersuchen.
Anfangscode
Hier ist der Dateicode
index.htmlin dem Tag, mit dem <body>wir beginnen werden:
<div id="app">
<div class="product">
<div class="product-image">
<img :src="image" />
</div>
<div class="product-info">
<h1>{{ title }}</h1>
<p v-if="inStock">In stock</p>
<p v-else>Out of Stock</p>
<p>Shipping: {{ shipping }}</p>
<ul>
<li v-for="detail in details">{{ detail }}</li>
</ul>
<div
class="color-box"
v-for="(variant, index) in variants"
:key="variant.variantId"
:style="{ backgroundColor: variant.variantColor }"
@mouseover="updateProduct(index)"
></div>
<button
v-on:click="addToCart"
:disabled="!inStock"
:class="{ disabledButton: !inStock }"
>
Add to cart
</button>
<div class="cart">
<p>Cart({{ cart }})</p>
</div>
</div>
</div>
</div>
Hier ist der Code
main.js:
var app = new Vue({
el: '#app',
data: {
product: 'Socks',
brand: 'Vue Mastery',
selectedVariant: 0,
details: ['80% cotton', '20% polyester', 'Gender-neutral'],
variants: [
{
variantId: 2234,
variantColor: 'green',
variantImage: './assets/vmSocks-green.jpg',
variantQuantity: 10
},
{
variantId: 2235,
variantColor: 'blue',
variantImage: './assets/vmSocks-blue.jpg',
variantQuantity: 0
}
],
cart: 0,
},
methods: {
addToCart() {
this.cart += 1;
},
updateProduct(index) {
this.selectedVariant = index;
console.log(index);
}
},
computed: {
title() {
return this.brand + ' ' + this.product;
},
image() {
return this.variants[this.selectedVariant].variantImage;
},
inStock(){
return this.variants[this.selectedVariant].variantQuantity;
}
}
})
Aufgabe
Es ist nicht erforderlich, dass sich alle Daten, Methoden und berechneten Eigenschaften in der Vue-Anwendung in der Root-Vue-Instanz befinden. Im Laufe der Zeit wird dies zu Code führen, der sehr schwer zu warten ist. Stattdessen möchten wir den Code in modulare Teile aufteilen, die einfacher zu bearbeiten sind und die Entwicklung flexibler machen.
Die Lösung des Problems
Beginnen wir damit, vorhandenen Code in eine neue Komponente zu verschieben.
So wird die
main.jsKomponente in der Datei registriert:
Vue.component('product', {})
Das erste Argument ist der Komponentenname unserer Wahl. Das zweite ist ein Optionsobjekt, das dem Objekt ähnelt, mit dem wir Vue in früheren Tutorials instanziiert haben.
In der Vue-Instanz haben wir eine Eigenschaft verwendet
el, um die Bindung an das DOM-Element zu organisieren. Im Fall einer Komponente wird eine Eigenschaft verwendet template, die den HTML-Code der Komponente definiert.
Beschreiben wir die Komponentenvorlage in einem Objekt mit Optionen:
Vue.component('product', {
template: `
<div class="product">
… // HTML-, product
</div>
`
})
Es gibt verschiedene Möglichkeiten, Vorlagen in Vue zu erstellen. Wir verwenden jetzt ein Vorlagenliteral, dessen Inhalt in Anführungszeichen eingeschlossen ist.
Wenn sich herausstellt, dass der Vorlagencode nicht in einem einzelnen Stammelement platziert wird, z. B. einem Element
<div>mit einer Klasse product, wird die folgende Fehlermeldung angezeigt:
Component template should contain exactly one root element
Mit anderen Worten, eine Komponentenvorlage kann nur ein Element zurückgeben.
Die folgende Vorlage ist beispielsweise gut geformt, da sie nur durch ein Element dargestellt wird:
Vue.component('product', {
template: `<h1>I'm a single element!</h1>`
})
Wenn die Vorlage jedoch mehrere Geschwister enthält, funktioniert sie nicht. Hier ist ein Beispiel für ein schlechtes Muster:
Vue.component('product', {
template: `
<h1>I'm a single element!</h1>
<h2>Not anymore</h2>
`
})
Als Ergebnis stellt sich heraus, dass, wenn eine Vorlage viele Elemente enthalten sollte, z. B. eine Reihe von Elementen, die in unserer
<div>Klasse enthalten sind product, diese Elemente in einem äußeren Containerelement platziert werden sollten. Infolgedessen enthält die Vorlage nur ein Stammelement.
Nachdem die Vorlage den HTML-Code enthält, der sich früher in der Datei befand
index.html, können wir der Komponente, die sich zuvor in der Root-Vue-Instanz befand, Daten, Methoden und berechnete Eigenschaften hinzufügen:
Vue.component('product', {
template: `
<div class="product">
…
</div>
`,
data() {
return {
//
}
},
methods: {
//
},
computed: {
//
}
})
Wie Sie sehen können, entspricht die Struktur dieser Komponente fast genau der Struktur der Vue-Instanz, mit der wir zuvor gearbeitet haben. Haben Sie bemerkt, dass
datadies jetzt keine Eigenschaft ist, sondern eine Methode eines Objekts mit Optionen? Warum ist das so?
Der Punkt ist, dass Komponenten häufig mit Plänen erstellt werden, um sie wiederzuverwenden. Wenn wir viele Komponenten haben
product, müssen wir sicherstellen, dass jede von ihnen ihre eigenen Entitätsinstanzen hat data. Da es datasich nun um eine Funktion handelt, die ein Objekt mit Daten zurückgibt, wird garantiert, dass jede Komponente ihren eigenen Datensatz erhält. Wenn die Entität datakeine Funktion wäre, dann jede Komponenteproduct, wo immer solche Komponenten verwendet wurden, würden die gleichen Daten enthalten. Dies widerspricht der Idee wiederverwendbarer Komponenten.
Nachdem wir den produktbezogenen Code in eine native Komponente verschoben haben
product, sieht der Code zur Beschreibung der Root-Vue-Instanz folgendermaßen aus:
var app = new Vue({
el: '#app'
})
Jetzt müssen wir nur noch die Komponente
productin den Dateicode einfügen index.html. Es wird so aussehen:
<div id="app">
<product></product>
</div>
Wenn Sie die Anwendungsseite jetzt neu laden, kehrt sie zum vorherigen Formular zurück.

Anwendungsseite
Wenn Sie sich jetzt die Vue-Entwicklertools ansehen, werden Sie feststellen, dass es eine Root-Entität und eine Produktkomponente gibt.

Analysieren der Anwendung mit Vue Developer Tools
Um die Wiederverwendbarkeit von Komponenten zu demonstrieren, fügen wir dem Code
index.htmleinige weitere Komponenten hinzuproduct. Auf diese Weise wird die Wiederverwendung von Komponenten organisiert. Der Codeindex.htmlsieht folgendermaßen aus:
<div id="app">
<product></product>
<product></product>
<product></product>
</div>
Auf der Seite werden drei Kopien der Produktkarte angezeigt.

Mehrere Produktkarten auf einer Seite angezeigt
Bitte beachten Sie, dass wir in Zukunft mit einer Komponente arbeiten werden
product, sodass der Code folgendermaßenindex.htmlaussehen wird:
<div id="app">
<product></product>
</div>
Aufgabe
Anwendungen benötigen häufig Komponenten, um Daten und Eingabeparameter von übergeordneten Entitäten zu akzeptieren. In diesem Fall ist das übergeordnete Element der Komponente
productdie Root-Vue-Instanz selbst.
Lassen Sie die Root-Vue-Instanz eine Beschreibung einiger Daten haben. Diese Daten geben an, ob der Benutzer ein Premium-Kontoinhaber ist. Der Code zur Beschreibung einer Vue-Instanz könnte folgendermaßen aussehen:
var app = new Vue({
el: '#app',
data: {
premium: true
}
})
Lassen Sie uns entscheiden, dass Premium-Benutzer Anspruch auf kostenlosen Versand haben.
Dies bedeutet, dass die Komponente unterschiedliche Versandkosteninformationen
productausgeben soll, je nachdem, was in die premiumRoot-Vue-Instanzeigenschaft geschrieben wird.
Wie kann ich die in der
premiumRoot-Vue-Instanzeigenschaft gespeicherten Daten an das untergeordnete Element senden, das die Komponente ist product?
Die Lösung des Problems
In Vue wird zum Übertragen von Daten von übergeordneten Entitäten zu untergeordneten Entitäten eine Objekteigenschaft mit Optionen verwendet,
propsdie von den Komponenten beschrieben werden. Dies ist ein Objekt, das die Eingabeparameter der Komponente beschreibt, deren Werte basierend auf den von der übergeordneten Entität empfangenen Daten festgelegt werden sollten.
Beginnen wir mit der Beschreibung der von der Komponente erwarteten Eingabeparameter
product. Fügen Sie dazu dem Objekt die entsprechende Eigenschaft mit den Optionen hinzu, die während der Erstellung verwendet wurden:
Vue.component('product', {
props: {
premium: {
type: Boolean,
required: true
}
},
// , ,
})
Beachten Sie, dass dies die integrierte Fähigkeit von Vue nutzt, um an eine Komponente übergebene Parameter zu validieren. Das heißt, zeigen wir , was die Art des Eingangsparameters
premiumist Booleanund was dieser Parameter durch Einstellung erforderlich ist , requiredauf true.
Nehmen Sie als Nächstes eine Änderung an der Vorlage vor, in der die an das Objekt übergebenen Parameter angezeigt werden. Indem
premiumwir den Eigenschaftswert auf der Seite anzeigen , stellen wir sicher, dass der von uns untersuchte Mechanismus ordnungsgemäß funktioniert.
<p>User is premium: {{ premium }}</p>
Bisher läuft alles gut. Die Komponente
productweiß, dass sie den für ihren Betrieb erforderlichen Typparameter erhält Boolean. Wir haben einen Ort vorbereitet, an dem die relevanten Daten angezeigt werden.
Wir haben den Parameter jedoch noch nicht an die
premiumKomponente übergeben. Sie können dies mit einem benutzerdefinierten Attribut tun, das der "Zeile" ähnelt, die zu einer Komponente führt, über die die Eingabeparameter übertragen werden können, insbesondere premium.
Ändern wir den Code in
index.html:
<div id="app">
<product :premium="premium"></product>
</div>
Lassen Sie uns die Seite aktualisieren.

Ausgabe der an die Komponente übergebenen Daten Die Eingabeparameter
werden jetzt an die Komponente übergeben. Sprechen wir über genau das, was wir gerade getan haben.
Wir übergeben der Komponente einen Eingabeparameter oder ein "benutzerdefiniertes Attribut"
premium. Wir binden dieses benutzerdefinierte Attribut mithilfe des Doppelpunktkonstrukts an eine Eigenschaftpremium, die in unseren Vue-Instanzdaten gespeichert ist.
Jetzt kann die Root-Vue-Instanz an die
premiumuntergeordnete Komponente übergeben werdenproduct. Da das Attribut an eine Eigenschaftpremiumaus den Vue-Instanzdatengebunden ist, wird der aktuelle Wertpremiumimmer an die Komponente übergebenproduct.
Das obige Bild, nämlich die Inschrift
User is premium: true, beweist, dass alles richtig gemacht wurde.
Jetzt haben wir überprüft, ob der von uns untersuchte Datenübertragungsmechanismus wie erwartet funktioniert. Wenn Sie sich die Vue-Entwicklertools ansehen, stellt sich heraus, dass die Komponente
Productjetzt über einen Eingabeparameter verfügt premium, in dem ein Wert gespeichert ist true.

Eingabeparameter der Komponente
Nachdem die Daten darüber, ob der Benutzer über ein Premium-Konto verfügt, in die Komponente gelangen, verwenden wir diese Daten, um die Versandkosteninformationen auf der Seite anzuzeigen. Vergessen wir nicht, dassder Benutzer Anspruch auf kostenlosen Versand hat, wenn der Parameter
premiumauf einen Wert eingestellttrueist. Erstellen wir eine neue berechnete Eigenschaftshippingund verwenden den darin enthaltenen Parameterpremium:
shipping() {
if (this.premium) {
return "Free";
} else {
return 2.99
}
}
Wenn in einem Parameter
this.premiumgespeichert true, wird die berechnete Eigenschaft shippingzurückgegeben Free. Andernfalls wird es zurückkehren 2.99.
Entfernen wir den Parameterwert-Ausgabecode aus der Komponentenvorlage
premium. Jetzt kann das Element <p>Shipping: {{ shipping }}</p>, das in dem Code enthalten war, mit dem wir heute begonnen haben, Informationen zu den Versandkosten anzeigen.

Premium - Nutzer erhalten kostenlose Lieferung
Text
Shipping: Freeerscheint auf der Seite aufgrund der Tatsachedass die Komponente eines Eingabeparameter übertragen wirdpremiumauf einen Wert gesetzttrue.
Wunderbar! Jetzt haben wir gelernt, wie Daten von übergeordneten Entitäten an untergeordnete Entitäten übertragen werden, und konnten diese Daten in der Komponente verwenden, um die Kosten für den Versand von Waren zu verwalten.
Übrigens ist es erwähnenswert, dass Sie ihre Eingabeparameter in untergeordneten Komponenten nicht ändern sollten.
Werkstatt
Erstellen Sie eine neue Komponente
product-details, die einen Eingabeparameter verwenden detailsund für das Rendern des Teils der Produktkarte verantwortlich sein soll, der zuvor mit dem folgenden Code erstellt wurde:
<ul>
<li v-for="detail in details">{{ detail }}</li>
</ul>
Hier ist eine Vorlage, mit der Sie dieses Problem lösen können.
Hier ist die Lösung des Problems.
Ergebnis
Heute war Ihre erste Einführung in Vue-Komponenten. Folgendes haben Sie gelernt:
- Komponenten sind Codeblöcke, die als benutzerdefinierte Elemente dargestellt werden.
- Komponenten erleichtern die Verwaltung Ihrer Anwendung, indem sie in wiederverwendbare Teile zerlegt werden. Sie enthalten Beschreibungen der visuellen Komponente und der Funktionalität des entsprechenden Teils der Anwendung.
- Komponentendaten werden durch eine Methode eines
data()Objekts mit Optionen dargestellt. - Eingabeparameter (
props) werden verwendet, um Daten von übergeordneten Entitäten an untergeordnete Entitäten zu übergeben . - Wir können die Anforderungen für die Eingabeparameter beschreiben, die die Komponente verwendet.
- .
- .
- Vue .
Verwenden Sie Vue-Entwicklertools?
→ Vue.js Anfänger Lektion 1: Instanz Vue
→ Vue.js für Anfänger, Lektion 2: Bindungsattribute
→ Vue.js Anfänger Lektion 3: Bedingtes Rendern
→ Vue.js Anfänger Lektion 4: Listen rendern
→ Vue .js für Anfänger Lektion 5: Ereignisverarbeitung
→ Vue.js Anfänger Lektion 6: Binden von Klassen und Stilen
→ Vue.js Anfänger Lektion 7: berechnete Eigenschaften
→ Vue.js Anfänger Lektion 8: Komponenten
