web-dev-qa-db-de.com

vue, emittierende vs Durchlassfunktion als Requisiten

Angenommen, ich habe eine Schaltflächenkomponente, die in mehrere andere Komponenten importiert wird. Ich möchte, dass die untergeordnete Komponente nicht an eine Art von Logik gekoppelt ist, die beim Klicken auf die Schaltfläche auftritt. Ich möchte diese Logik in den verschiedenen Komponenten, die diese Button-Komponente nutzen, festhalten.

Ich denke, dass es mindestens zwei Möglichkeiten gibt, dies zu tun. 

  1. Lassen Sie das Kind ein Ereignis an die Eltern ausgeben, und lassen Sie dann die Eltern den Handler definieren.

  2. Definieren Sie die Handler in den Eltern und übergeben Sie sie als Requisiten an die Button-Komponente.

Ich bin es gewohnt, Letzteres in React zu tun. Gibt es eine bewährte Praxis für diese Situation?

6
Andrew Kim

Die Vue-Philosophie ist nach unten gerichtet. Die erste Option ergibt sich aus der Annäherung, während das Ereignis selbst an das übergeordnete Element gesendet und dann behandelt wird.

Innerhalb eines Vue-SFCs haben Sie den zusätzlichen Vorteil, dass das gebundene Attribut mit einem v-on (oder @) vorangestellt wird, das seine Absicht als Ereignis beschreibt, das aufwärts abläuft, und nicht als v-bind (oder :) Es ist wirklich ein Rückruf auf eine Veranstaltung.

10
Shelton Clinard

Beste Übung

Die bewährte Methode wäre Option Nummer 1. Diese Vorgehensweise wird in der offiziellen Dokumentation verwendet: https://vuejs.org/v2/guide/components.html#Sending-Messages-to-Parents-mit-Events

Performance

Solange Sie einen Verweis auf eine Funktion übergeben, die ausgeführt wird, wenn Sie den Event-Bus verwenden oder als Requisite übergehen, sollten Sie fast keinen Leistungsunterschied sehen.

Beispiel mit Optionsnummer 1

Sie können this.$emit('eventName', dataToSend, ...) verwenden, um die Daten an die übergeordnete Komponente zu senden, die dann die Komponente wie diesen <my-component @eventName="yourHandler" /> abhören würde. Sie können dann für jede Taste eine andere Logik verwenden.

Ich habe eine Geige für eine Multi-Select-Komponente erstellt, die Folgendes implementiert: https://jsfiddle.net/wkdL0xbc/

// HTML
<div id="app">
  <multi-choice :items="myItems" @selected="alert($event)"></multi-choice>
  <multi-choice :items="myItems" @selected="sayIsCool"></multi-choice>
</div>

// JavaScript
const multiChoice = {
    template: '<div class="multi-choice"><span v-for="item in items" @click="select(item)">{{ item }}</span></div>',
  props: ['items'],
  methods: {
    select(item) {
        this.$emit('selected', item);
    }
  }
};

new Vue({
  el: "#app",
  data() {
    return {
        myItems: [
        'Homer',
        'Marge',
        'Bart'
      ],
    }
  },
  components: {
    multiChoice: multiChoice
  },
  methods: {
    sayIsCool(item) {
        alert(item + ' is cool!')
    }
  }
})
4
atlazor

Ich studiere immer noch Vue.js und würde mich freuen, wenn sich hier Unstimmigkeiten ergeben.


Vue.js events sind Rückrufe, sie sind keine DOM-Ereignisse. Sie können dies überprüfen, da Sie dem Ereignis-Listener einen benutzerdefinierten Namen und keinen DOM-Ereignisnamen (click, focus...) hinzufügen. Außerdem wird kein event-Objekt an die Funktion übergeben, es sei denn, Sie geben im Aufruf $event ein $emit-Argument an .

Veranstaltungen

Pros

  • Für Bibliotheken: Dies macht es leichter und die Clients haben mehr Flexibilität bei der Verwendung von Methoden
  • Hilfreiche Vue devtools-Ereignisprotokollierung
  • Erlaube den globalen Listener (this.$root.on), obwohl dies durch Vuex.js. besser verbessert werden kann.
  • Differenzierte Syntax: : für Requisiten und @ für Ereignisse/Methoden

Cons

  • Weniger explizit, schwieriger zu debuggen (fehlgeschlagen, wenn keine Listener vorhanden sind oder der Ereignisname falsch geschrieben ist)

Requisiten

Pros

  • Expliziter, deklarativ, kann als Standard festgelegt, erforderlich, validiert werden, was das Debuggen erleichtert (Laufzeitfehler oder Kompilierungsfehler in TypeScript).

Cons

  • Sie müssen Requisitenvalidierung einschließen, damit Sie nicht vor dem Aufruf prüfen müssen, ob eine function() -Eigenschaft vorhanden ist (aber die Validierung von Requisiten ist ohnehin eine gute Praxis ...).

Fazit

Sieht aus, als wären die Ansätze mehr Konvention und persönliche Präferenz vor allem anderen, obwohl ich denke, wenn nicht die Dokumentation von Vue.js dem events -Vorzug den Vorzug geben würde, würde jeder gerne Requisiten nur, was meiner Meinung nach besser ist

Props kann alles, was Ereignisse tut, mit Ausnahme einiger weniger Fälle (wie $root Ereignis-Abhörmuster - Hinweis: Vuex.js ersetzt diese Funktion und wird aus Gründen der Skalierbarkeit bevorzugt), mit dem Vorteil, dass sie vorteilhaft sind expliziter, fehlerhafter und prüfanfälliger. 

Zusammengefasst aus: https://forum.vuejs.org/t/events-vs-callback-props/11451

3
jpenna

Sie suchen nach "Transparent Wrappers"

Das Zollereignis von Vue funktioniert anders als ein natives DOM-Ereignis. Sie müssen also dem Ereignis eine .native-Eigenschaft hinzufügen

Wenn Sie jedoch möchten, dass das Ereignis auf dem untergeordneten Element ausgeführt wird, definieren Sie eine berechnete Eigenschaft, die zurückgegeben wird, und ein Objekt von Listenern. Und jetzt wirst du nicht

Attribute, die nicht als Requisiten definiert sind, werden standardmäßig dem Stammelement der Ansicht hinzugefügt

So können Sie VererbungAttrs: false festlegen und dann die $ attrs an das untergeordnete Objekt binden. Anschließend werden diese Attribute zum Ziel

Jetzt müssen Sie nicht mehr darüber nachdenken, was die Wurzelkomponente ist.

Chris Fritz macht einen großartigen Job und erklärt, wie sie in seinen 7 geheimen Gesprächsmustern arbeiten. Beginnt um 21:44 https://youtu.be/7lpemgMhi0k?t=21m44s

0
Adam Bradford