Vue.js fĂŒr AnfĂ€nger Lektion 9: Benutzerdefinierte Ereignisse

In der vorherigen Lektion in unserem Vue-Kurs haben Sie gelernt, wie Sie Komponenten erstellen und Daten von ĂŒbergeordneten EntitĂ€ten mithilfe des Requisitenmechanismus an untergeordnete EntitĂ€ten ĂŒbergeben. Was ist, wenn die Daten in die entgegengesetzte Richtung ĂŒbertragen werden mĂŒssen? In der neunten Lektion lernen Sie heute, wie Sie eine wechselseitige Kommunikation zwischen Komponenten verschiedener Ebenen herstellen.







→ 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

→ Vue. js fĂŒr AnfĂ€nger Lektion 9: Benutzerdefinierte Ereignisse



Der Zweck der Lektion



Wir möchten, dass die Komponente productder ĂŒbergeordneten EntitĂ€t, der Root-Vue-Instanz, mitteilen kann, dass ein Ereignis aufgetreten ist. In diesem Fall muss es productzusammen mit der Benachrichtigung ĂŒber das Auftreten des Ereignisses einige Daten senden.



Anfangscode



Die index.htmlTutorial-Projektdatei enthÀlt jetzt den folgenden Code:



<div id="app">
  <product :premium="premium"></product>
</div>


Hier ist der Inhalt der Datei main.js:



Vue.component('product', {
  props: {
    premium: {
      type: Boolean,
      required: true
    }
  },
  template: `
  <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>
  `,
  data() {
    return {
      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;
      },
      shipping() {
        if (this.premium) {
          return "Free";
        } else {
          return 2.99
        }
      }
    }
})

var app = new Vue({
  el: '#app',
  data: {
    premium: true
  }
})


Aufgabe



Wenn es nun productals eigenstĂ€ndige Komponente dargestellt wird, productmacht es keinen Sinn, dass sich der Code fĂŒr den Warenkorb darin befindet . Wenn jedes Produkt einen eigenen Warenkorb hat, dessen Status wir ĂŒberwachen mĂŒssen, wird unsere Anwendung zu einem großen Durcheinander. Stattdessen möchten wir, dass der Einkaufswagen im Stammverzeichnis der Vue-Instanz vorhanden ist. Wir benötigen die Komponente auch, productum die Root-Vue-Instanz ĂŒber das HinzufĂŒgen von Artikeln zum Warenkorb zu informieren, dh ĂŒber das Klicken auf die SchaltflĂ€che Add to cart.



Entscheidung



Verschieben wir die Daten zum Warenkorb zurĂŒck in die Root-Vue-Instanz:



var app = new Vue({
  el: '#app',
  data: {
    premium: true,
    cart: 0
  }
})


Als nĂ€chstes verschieben wir die Warenkorbvorlage zurĂŒck zu index.htmlund bringen ihren Code in dieses Formular:



<div id="app">
  <div class="cart">
    <p>Cart({{ cart }})</p>
  </div>

  <product :premium="premium"></product>
</div>


Wenn Sie nun die Anwendungsseite in einem Browser öffnen und auf die SchaltflÀche klicken Add to cart, geschieht nichts wie erwartet.





Das Klicken auf die SchaltflĂ€che In den Warenkorb fĂŒhrt noch zu nichts



. Was soll passieren, wenn auf diese SchaltflÀche geklickt wird? Wenn Sie darauf klicken, erhÀlt die Root-Vue-Instanz eine Benachrichtigung, die eine Methode aufruft, die den Warenkorb auf den neuesten Stand bringt, dh den darin gespeicherten Wert aktualisiertcart.



Um dies zu erreichen, schreiben wir zuerst den Code deraddToCartKomponentenmethode neuproduct.



Jetzt sieht es so aus:



addToCart() {
  this.cart += 1;
},


Lassen Sie es uns auf diese Form bringen:



addToCart() {
  this.$emit('add-to-cart');
},


Was bedeutet das alles?



So ist es also. Wenn die Methode aufgerufen wird addToCart, wird ein benutzerdefiniertes Ereignis generiert add-to-cart. Mit anderen Worten, wenn auf die SchaltflĂ€che Add to cartgeklickt wird, wird eine Methode aufgerufen, die ein Ereignis generiert, das angibt, dass die SchaltflĂ€che gerade gedrĂŒckt wurde (dh, dass das durch das Klicken auf die SchaltflĂ€che ausgelöste Ereignis gerade aufgetreten ist).



Im Moment wartet jedoch nichts in der Anwendung darauf, dass dieses Ereignis eintritt oder darauf wartet. FĂŒgen wir einen Ereignis-Listener hinzu zu index.html:



<product :premium="premium" @add-to-cart="updateCart"></product>


Hier verwenden wir das Ansichtskonstrukt @add-to-cardgenauso wie das Konstrukt :premium. Wenn es sich jedoch :premiumum eine "Pipeline" handelt, ĂŒber die Daten von der ĂŒbergeordneten Komponente an die untergeordnete Komponente ĂŒbertragen werden können, @add-to-cartkann sie mit dem "FunkempfĂ€nger" der ĂŒbergeordneten Komponente verglichen werden, der von der untergeordneten Komponente Informationen empfĂ€ngt, dass eine Taste gedrĂŒckt wurde Add to cart. Da sich das "Radio" in einem <product>verschachtelten Tag befindet <div id="app">, bedeutet dies, dass beim Eintreffen von Informationen zu einem Klick die in der Root-Vue-Instanz befindliche Add to cartMethode aufgerufen wird updateCart. In die normale Sprache



ĂŒbersetzt @add-to-cart=«updateCart»sieht der Code folgendermaßen aus: "Wenn Sie hören, dass ein Ereignis aufgetreten ist add-to-cart, rufen Sie die Methode auf updateCart."



Diese Methode, die jetzt im Optionsobjekt deklariert wird, das beim Instanziieren von Vue verwendet wird, haben Sie wahrscheinlich irgendwo gesehen:



methods: {
  updateCart() {
    this.cart += 1;
  }
}


TatsĂ€chlich ist dies genau die gleiche Methode, die frĂŒher verwendet wurde product. Aber jetzt befindet es sich in der Root-Vue-Instanz und wird auf Knopfdruck aufgerufen Add to cart.









SchaltflÀche funktioniert wieder Wenn Sie auf eine SchaltflÀche in einer Komponente klickenproduct, wird eine Methode aufgerufenaddToCart, die ein Ereignis generiert. Die Root-Vue-Instanz "Radio hören" erfÀhrt, dass dieses Ereignis aufgetreten ist, und ruft eine Methode aufupdateCart, die die in gespeicherte Nummer erhöhtcart.



Wir haben unser Ziel erreicht, aber in einer realen Anwendung bringt das Wissen, dass ein Ereignis eingetreten ist, dass ein bestimmtes Produkt in den Warenkorb gelegt wurde, keinen großen Nutzen. In Wirklichkeit mĂŒssen Sie mindestens wissen, welches Produkt dem Warenkorb hinzugefĂŒgt wurde. Dies bedeutet, dass Sie in dem Fall, der als Reaktion auf das DrĂŒcken der Taste generiert wird, auch einige Daten ĂŒbertragen mĂŒssen.



Die im Ereignis ĂŒbergebenen Daten können als das zweite Argument beschrieben werden, das$emitim Code deraddToCartKomponentenmethode ĂŒbergebenwirdproduct::



this.$emit('add-to-cart', this.variants[this.selectedVariant].variantId);


Jetzt ĂŒbergibt das Ereignis die Kennung ( variantId) des Produkts, das der Benutzer dem Warenkorb hinzufĂŒgen möchte. Dies bedeutet, dass wir nicht nur die Anzahl der Artikel im Warenkorb erhöhen, sondern auch detailliertere Informationen zu den hinzugefĂŒgten Artikeln im Warenkorb speichern können. Dazu konvertieren wir zuerst den Warenkorb in ein Array, indem wir ein leeres Array schreiben in cart:



cart: []


Als nĂ€chstes schreiben wir die Methode neu updateCart. Erstens - es wird jetzt akzeptiert id- dieselbe Produktkennung, die jetzt im Ereignis ĂŒbergeben wird, und zweitens - es wird jetzt das, was es empfangen hat, in ein Array einfĂŒgen:



methods: {
  updateCart(id) {
    this.cart.push(id);
  }
}


Nach einem einzigen Klick auf die SchaltflĂ€che wird die Produktkennung zum Array hinzugefĂŒgt. Das Array wird auf der Seite angezeigt.





Das Array mit der Produkt-ID wird auf der Seite angezeigt.



Es muss nicht das gesamte Array auf der Seite angezeigt werden . Wir werden mit der Ausgabe der Anzahl der Produkte zufrieden sein, die dem Warenkorb, dh dem Array, hinzugefĂŒgt wurdencart. Daher können wir den Tag-Code neu schreiben<p>, der Informationen ĂŒber die Anzahl der zum Warenkorb hinzugefĂŒgten Produkte wie folgt anzeigt:



<p>Cart({{ cart.length }})</p>




Auf der Seite werden Informationen zur Anzahl der Artikel



angezeigt, die dem Warenkorb hinzugefĂŒgt wurden. Jetzt zeigen wir einfach die LĂ€nge des Arrays auf der Seite oder mit anderen Worten die Anzahl der Artikel im Warenkorb an. Äußerlich sieht der Warenkorb genauso aus wie zuvor, aber anstatt einfach den Wert einer numerischen Eigenschaft zu erhöhencart, speichern wirjetztin einem Array diecartInformationen darĂŒber, welcher bestimmte Artikel dem Warenkorb hinzugefĂŒgt wurde.



Werkstatt



FĂŒgen Sie dem Projekt eine SchaltflĂ€che carthinzu , mit der das zuvor zuvor hinzugefĂŒgte Produkt aus dem Array entfernt wird . Durch Klicken auf diese SchaltflĂ€che sollte ein Ereignis generiert werden, das Informationen zur Kennung des Artikels enthĂ€lt, der aus dem Warenkorb entfernt werden soll.





Ergebnis



Folgendes haben Sie heute gelernt:



  • Eine Komponente kann die ĂŒbergeordnete EntitĂ€t mithilfe des Konstrukts darĂŒber informieren, dass etwas in ihr passiert ist $emit.
  • Eine ĂŒbergeordnete Komponente kann einen Ereignishandler verwenden, der mithilfe der Direktive v-on(oder ihrer Kurzversion @) definiert wurde, um eine Antwort auf Ereignisse zu organisieren, die von untergeordneten Komponenten generiert werden. Wenn ein Ereignis auftritt, kann ein Ereignishandler in der ĂŒbergeordneten Komponente aufgerufen werden.
  • , , .


Wenn Sie den Kurs studieren und zu dieser Lektion gekommen sind, teilen Sie uns bitte mit, fĂŒr welchen Zweck Sie arbeiten und was Sie durch das Beherrschen von Vue erreichen möchten.



→ 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

→ Vue. js fĂŒr AnfĂ€nger Lektion 9: Benutzerdefinierte Ereignisse






All Articles