Vue.js für Anfänger Lektion 8: Komponenten

Heute, in der achten Lektion des Vue-Kurses, werden Sie zum ersten Mal mit Komponenten in Berührung kommen. Komponenten sind wiederverwendbare Codeblöcke, die sowohl das Erscheinungsbild von Teilen der Anwendung als auch die Implementierung von Projektfunktionen umfassen können. Sie helfen Programmierern beim Erstellen einer modularen Codebasis, die einfach zu warten ist. Vue.js Anfänger Lektion 1: Instanz VueVue.js für Anfänger, Lektion 2: BindungsattributeVue.js Anfänger Lektion 3: Bedingtes RendernVue.js Anfänger Lektion 4: Listen rendernVue .js für Anfänger Lektion 5: EreignisbehandlungVue.js für Anfänger Lektion 6: Bindungsklassen und -stile



















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 Codeindex.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 werdenproduct, 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 diepremiumuntergeordnete 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 InschriftUser 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 Parameterpremiumauf 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



TextShipping: 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






All Articles